abnf_parser/
parser.rs

1//
2// ABNF parser - Parse ABNF file and dump rulelist.
3//   Copyright (C) 2021 Toshiaki Takada
4//
5
6use std::cell::Cell;
7use std::env;
8use std::fs::File;
9use std::io::prelude::*;
10use std::io::Error;
11use std::io::ErrorKind;
12use std::path::Path;
13
14use super::element::*;
15use super::error::*;
16
17/// ABNF Token type.
18#[derive(PartialEq, Debug)]
19pub enum Token {
20    Whitespace(String),
21    Comment(String),
22    Rulename(String),
23    DefinedAs,
24    Incremental,
25    IString(String),
26    SString(String),
27    NumberValue(u32),
28    ValueRange((u32, u32)),
29    ValueSequence(Vec<u32>),
30    ProseVal(String),
31    OptionalBegin,
32    OptionalEnd,
33    GroupingBegin,
34    GroupingEnd,
35    Repeat(Repeat),
36    Separator,
37    Unknown,
38}
39
40// Parser, to keep state while parsing.
41pub struct Parser {
42    /// Input string.
43    input: String,
44    /// Cursor position in bytes from the beginning.
45    pos: Cell<usize>,
46    /// Line number at cursor.
47    line: Cell<usize>,
48}
49
50impl Parser {
51    /// Constructor.
52    pub fn new(s: String) -> Parser {
53        Parser {
54            input: s,
55            pos: Cell::new(0),
56            line: Cell::new(0),
57        }
58    }
59
60    /// Get input string at current position.
61    pub fn input(&self) -> &str {
62        &self.input[self.pos.get()..]
63    }
64
65    /// Return remaining input length.
66    pub fn input_len(&self) -> usize {
67        self.input.len() - self.pos.get()
68    }
69
70    /// Return parser cusor position.
71    pub fn pos(&self) -> usize {
72        self.pos.get()
73    }
74
75    /// Set cursor position.
76    pub fn pos_set(&mut self, pos: usize) {
77        self.pos.set(self.pos.get() + pos);
78    }
79
80    /// Return line number.
81    pub fn line(&self) -> usize {
82        self.line.get()
83    }
84
85    /// Add len to line number.
86    pub fn line_add(&self, len: usize) {
87        self.line.set(self.line.get() + len);
88    }
89
90    /// Get single token and parsed length.
91    pub fn get_token(&mut self) -> Result<Token, AbnfParseError> {
92        let input = &self.input();
93        let token: Token;
94        let mut pos: usize = 0;
95
96        if input.starts_with(char::is_whitespace) {
97            pos = match input.find(|c: char| !c.is_whitespace()) {
98                Some(pos) => pos,
99                None => input.len(),
100            };
101            let l = &input[..pos];
102            let v: Vec<&str> = l.matches("\n").collect();
103            self.line_add(v.len());
104
105            token = Token::Whitespace(String::from(l));
106        } else if input.starts_with(';') {
107            pos = match input.find(|c: char| c == '\r' || c == '\n') {
108                Some(pos) => pos,
109                None => input.len(),
110            };
111
112            token = Token::Comment(String::from(&input[1..pos]));
113        } else if input.starts_with("=/") {
114            pos = 2;
115            token = Token::Incremental;
116        } else if input.starts_with('=') {
117            pos = 1;
118            token = Token::DefinedAs;
119        } else if input.starts_with('"') {
120            let l = &input[1..];
121            pos = match l.find(|c: char| c == '"') {
122                Some(pos) => pos,
123                None => return Err(AbnfParseError::TokenParseError),
124            };
125
126            token = Token::IString(String::from(&l[..pos]));
127            pos += 2;
128        } else if input.starts_with(char::is_alphabetic) {
129            pos = match input.find(|c: char| !c.is_alphanumeric() && c != '-') {
130                Some(pos) => pos,
131                None => input.len(),
132            };
133
134            token = Token::Rulename(String::from(&input[..pos]));
135        } else if input.starts_with('%') {
136            let mut l = &input[1..];
137            if l.starts_with(|c: char| c == 's' || c == 'i') {
138                let case = if l.starts_with('s') { true } else { false };
139
140                l = &input[2..];
141                if !l.starts_with('"') {
142                    return Err(AbnfParseError::TokenParseError);
143                }
144
145                l = &input[3..];
146                pos = match l.find(|c: char| c == '"') {
147                    Some(pos) => pos,
148                    None => return Err(AbnfParseError::TokenParseError),
149                };
150
151                if case {
152                    token = Token::SString(String::from(&l[..pos]));
153                } else {
154                    token = Token::IString(String::from(&l[..pos]));
155                }
156                pos += 4;
157            } else if l.starts_with(|c: char| c == 'b' || c == 'd' || c == 'x') {
158                let radix = if l.starts_with('b') {
159                    2
160                } else if l.starts_with('d') {
161                    10
162                } else {
163                    16
164                };
165
166                l = &l[1..];
167                pos = match l.find(|c: char| !c.is_alphanumeric() && c != '.' && c != '-') {
168                    Some(pos) => pos,
169                    None => l.len(),
170                };
171
172                l = &l[..pos];
173
174                if let Some(_) = l.find('-') {
175                    let v: Vec<&str> = l.split("-").collect();
176                    if v.len() != 2 {
177                        return Err(AbnfParseError::TokenParseError);
178                    }
179
180                    let rbegin = u32::from_str_radix(v[0], radix)?;
181                    let rend = u32::from_str_radix(v[1], radix)?;
182
183                    token = Token::ValueRange((rbegin, rend));
184                } else if let Some(_) = l.find('.') {
185                    let v: Vec<u32> = l
186                        .split(".")
187                        .map(|s| u32::from_str_radix(s, radix).unwrap())
188                        .collect();
189                    token = Token::ValueSequence(v);
190                } else {
191                    let val = u32::from_str_radix(l, radix)?;
192                    token = Token::NumberValue(val);
193                }
194
195                pos += 2;
196            } else {
197                return Err(AbnfParseError::TokenParseError);
198            }
199        } else if input.starts_with('<') {
200            let l = &input[1..];
201            pos = match l.find(|c: char| c == '>') {
202                Some(pos) => pos,
203                None => return Err(AbnfParseError::TokenParseError),
204            };
205            token = Token::ProseVal(String::from(&input[1..pos + 1]));
206            pos += 2;
207        } else if input.starts_with('(') {
208            token = Token::GroupingBegin;
209            pos = 1;
210        } else if input.starts_with(')') {
211            token = Token::GroupingEnd;
212            pos = 1;
213        } else if input.starts_with('[') {
214            token = Token::OptionalBegin;
215            pos = 1;
216        } else if input.starts_with(']') {
217            token = Token::OptionalEnd;
218            pos = 1;
219        } else if input.starts_with('/') {
220            token = Token::Separator;
221            pos = 1;
222        } else if input.starts_with(|c: char| (c >= '1' && c <= '9') || c == '*') {
223            let mut min: Option<usize> = None;
224            let mut max: Option<usize> = None;
225            let mut num: usize = 0;
226            let mut l = &input[..];
227
228            loop {
229                if !l.starts_with(char::is_numeric) {
230                    break;
231                }
232
233                num *= 10;
234                num += l.chars().next().unwrap().to_digit(10).unwrap() as usize;
235                pos += 1;
236
237                l = &l[1..];
238            }
239
240            if num > 0 {
241                min = Some(num);
242            }
243
244            if !l.starts_with(|c: char| c == '*') {
245                max = min;
246            } else {
247                l = &l[1..];
248                pos += 1;
249                num = 0;
250
251                loop {
252                    if !l.starts_with(char::is_numeric) {
253                        break;
254                    }
255
256                    num *= 10;
257                    num += l.chars().next().unwrap().to_digit(10).unwrap() as usize;
258                    pos += 1;
259
260                    l = &l[1..];
261                }
262                if num > 0 {
263                    max = Some(num);
264                }
265            }
266
267            token = Token::Repeat(Repeat::new(min, max));
268        } else {
269            return Err(AbnfParseError::TokenParseError);
270        }
271        self.pos_set(pos);
272        Ok(token)
273    }
274
275    /// Parser parse entry point.  Return a rulelist.
276    pub fn parse(&mut self) -> Result<Rulelist, AbnfParseError> {
277        let mut rulelist = Rulelist::new();
278        let mut rulename = None;
279
280        while self.input_len() > 0 {
281            // 1. find Rulename.
282            loop {
283                let token = self.get_token()?;
284                match token {
285                    Token::Whitespace(_) | Token::Comment(_) => {
286                        // Do nothing.
287                    }
288                    Token::Rulename(name) => {
289                        rulename.replace(name);
290                        break;
291                    }
292                    _ => return Err(AbnfParseError::ExpectRulename(token)),
293                }
294
295                if self.input_len() == 0 {
296                    return Err(AbnfParseError::ExpectRulename(token));
297                }
298            }
299
300            // 2. find defined-as (=) or Incremental Alternatives(=/).
301            loop {
302                let token = self.get_token()?;
303                match token {
304                    Token::Whitespace(_) | Token::Comment(_) => {
305                        // Do nothing.
306                    }
307                    Token::DefinedAs => {
308                        let rulename = rulename.take().unwrap();
309
310                        match rulelist.get(&rulename) {
311                            Some(_) => return Err(AbnfParseError::RuleExist),
312                            None => {
313                                match self.parse_rule() {
314                                    Ok(rep) => rulelist.insert(rulename, rep),
315                                    Err(err) => return Err(err),
316                                };
317                            }
318                        }
319
320                        break;
321                    }
322                    Token::Incremental => {
323                        let rulename = rulename.take().unwrap();
324
325                        match rulelist.remove(&rulename) {
326                            Some(rep) => {
327                                let mut v = match rep.element {
328                                    Element::Selection(v) => v,
329                                    _ => vec![rep.clone()],
330                                };
331
332                                match self.parse_rule() {
333                                    // If one or both rep(s) is/are selection, try to merge.
334                                    Ok(rep) => match rep.element {
335                                        Element::Selection(mut w) => v.append(&mut w),
336                                        _ => v.push(rep),
337                                    },
338                                    Err(err) => return Err(err),
339                                }
340
341                                rulelist
342                                    .insert(rulename, Repetition::new(None, Element::Selection(v)));
343                            }
344                            None => return Err(AbnfParseError::RuleNotExist),
345                        }
346
347                        break;
348                    }
349                    _ => return Err(AbnfParseError::ExpectDefinedAs),
350                }
351
352                if self.input_len() == 0 {
353                    return Err(AbnfParseError::ExpectDefinedAs);
354                }
355            }
356        }
357
358        Ok(rulelist)
359    }
360
361    /// Recursively parse input and find rules.
362    pub fn parse_rule(&mut self) -> Result<Repetition, AbnfParseError> {
363        let mut v: Vec<Repetition> = Vec::new();
364        let mut repeat: Option<Repeat> = None;
365        let mut separator = false;
366        let mut sv: Vec<Repetition> = Vec::new();
367
368        while self.input_len() > 0 {
369            let token = self.get_token()?;
370            match token {
371                Token::Whitespace(ws) => {
372                    if is_rule_delimiter(&ws) {
373                        break;
374                    }
375                    continue;
376                }
377                Token::Comment(_) => {
378                    continue;
379                }
380                Token::Rulename(name) => {
381                    v.push(Repetition::new(repeat.take(), Element::Rulename(name)));
382                }
383                Token::IString(val) => {
384                    v.push(Repetition::new(repeat.take(), Element::IString(val)));
385                }
386                Token::SString(val) => {
387                    v.push(Repetition::new(repeat.take(), Element::SString(val)));
388                }
389                Token::NumberValue(val) => {
390                    v.push(Repetition::new(repeat.take(), Element::NumberValue(val)));
391                }
392                Token::ValueRange(val) => {
393                    v.push(Repetition::new(repeat.take(), Element::ValueRange(val)));
394                }
395                Token::ValueSequence(val) => {
396                    v.push(Repetition::new(repeat.take(), Element::ValueSequence(val)));
397                }
398                Token::ProseVal(val) => {
399                    v.push(Repetition::new(repeat.take(), Element::ProseValue(val)));
400                }
401                Token::OptionalBegin => {
402                    let mut rep = self.parse_rule()?;
403                    rep.repeat.replace(Repeat::new(Some(0), Some(1)));
404                    v.push(rep);
405                }
406                Token::OptionalEnd => {
407                    break;
408                }
409                Token::GroupingBegin => {
410                    let mut rep = self.parse_rule()?;
411                    rep.repeat = repeat.take();
412                    v.push(rep);
413                }
414                Token::GroupingEnd => {
415                    break;
416                }
417                Token::Repeat(r) => {
418                    repeat.replace(r);
419                }
420                Token::Separator => {
421                    separator = true;
422                    if v.len() == 1 {
423                        sv.push(v.pop().unwrap());
424                    } else {
425                        sv.push(Repetition::new(
426                            None,
427                            Element::Sequence(v.drain(..).collect()),
428                        ));
429                    }
430                }
431                _ => {
432                    return Err(AbnfParseError::UnexpectedToken(token));
433                }
434            }
435        }
436
437        if separator {
438            if v.len() == 1 {
439                sv.push(v.pop().unwrap());
440            } else {
441                sv.push(Repetition::new(
442                    None,
443                    Element::Sequence(v.drain(..).collect()),
444                ));
445            }
446            Ok(Repetition::new(None, Element::Selection(sv)))
447        } else if v.len() == 1 {
448            Ok(v.pop().unwrap())
449        } else {
450            Ok(Repetition::new(None, Element::Sequence(v)))
451        }
452    }
453}
454
455/// Return true if a given line has more than 2 "\n".
456fn is_rule_delimiter(input: &str) -> bool {
457    let v: Vec<&str> = input.matches("\n").collect();
458
459    if v.len() > 1 {
460        true
461    } else {
462        false
463    }
464}
465
466/// Open and parse an ABNF definition file.
467pub fn parse_file(filename: &str) -> std::io::Result<()> {
468    let mut f = File::open(filename)?;
469    let mut s = String::new();
470    let p = Path::new(filename)
471        .file_stem()
472        .ok_or(Error::new(ErrorKind::Other, "Invalid filename"))?;
473    let n1 = p
474        .to_str()
475        .ok_or(Error::new(ErrorKind::Other, "Invalid filename"))?;
476    let n2 = str::replace(n1, ".", "_");
477
478    f.read_to_string(&mut s)?;
479    let mut parser = Parser::new(s);
480
481    match parser.parse() {
482        Ok(rl) => {
483            rulelist_dump(&n2, &rl)?;
484        }
485        Err(err) => {
486            println!(
487                "Error: {:?} at line {}, pos {}",
488                err,
489                parser.line(),
490                parser.pos()
491            );
492        }
493    }
494
495    Ok(())
496}
497
498pub fn rulelist_dump(name: &str, rl: &Rulelist) -> std::io::Result<()> {
499    let manifest_dir = env!("CARGO_MANIFEST_DIR");
500    let path = Path::new(&manifest_dir).join("src/element.rs");
501    let mut file = File::open(path)?;
502    let mut elem = String::new();
503    file.read_to_string(&mut elem)?;
504    println!("{}", elem);
505
506    println!(r#"pub fn get_{}_rulelist() -> Rulelist {{"#, name);
507    println!(r#"    let mut rl: Rulelist = Rulelist::new();"#);
508    println!(r#""#);
509
510    for (k, v) in rl {
511        println!(r#"    rl.insert("{}".to_string(), {:?});"#, k, v);
512    }
513
514    println!(r#""#);
515    println!(r#"    rl"#);
516    println!(r#"}}"#);
517
518    Ok(())
519}
520
521#[cfg(test)]
522mod test {
523    use super::*;
524
525    #[test]
526    pub fn test_get_token_1() {
527        let str = "  abc ";
528        let mut parser = Parser::new(str.to_string());
529
530        let token = parser.get_token().unwrap();
531        assert_eq!(token, Token::Whitespace("  ".to_string()));
532
533        let token = parser.get_token().unwrap();
534        assert_eq!(token, Token::Rulename("abc".to_string()));
535
536        let token = parser.get_token().unwrap();
537        assert_eq!(token, Token::Whitespace(" ".to_string()));
538    }
539
540    #[test]
541    pub fn test_get_token_2() {
542        let str = "10*29DIGIT";
543        let mut parser = Parser::new(str.to_string());
544
545        let token = parser.get_token().unwrap();
546        assert_eq!(token, Token::Repeat(Repeat::new(Some(10), Some(29))));
547
548        let token = parser.get_token().unwrap();
549        assert_eq!(token, Token::Rulename("DIGIT".to_string()));
550    }
551
552    #[test]
553    pub fn test_get_token_3() {
554        let str = "(name)";
555        let mut parser = Parser::new(str.to_string());
556
557        let token = parser.get_token().unwrap();
558        assert_eq!(token, Token::GroupingBegin);
559
560        let token = parser.get_token().unwrap();
561        assert_eq!(token, Token::Rulename("name".to_string()));
562
563        let token = parser.get_token().unwrap();
564        assert_eq!(token, Token::GroupingEnd);
565    }
566
567    #[test]
568    pub fn test_get_token_4() {
569        let str = "\n\n\nabc\ndef\n\n";
570        let mut parser = Parser::new(str.to_string());
571
572        let token = parser.get_token().unwrap();
573        assert_eq!(token, Token::Whitespace("\n\n\n".to_string()));
574        assert_eq!(parser.line(), 3);
575
576        let token = parser.get_token().unwrap();
577        assert_eq!(token, Token::Rulename("abc".to_string()));
578        assert_eq!(parser.line(), 3);
579
580        let token = parser.get_token().unwrap();
581        assert_eq!(token, Token::Whitespace("\n".to_string()));
582        assert_eq!(parser.line(), 4);
583
584        let token = parser.get_token().unwrap();
585        assert_eq!(token, Token::Rulename("def".to_string()));
586        assert_eq!(parser.line(), 4);
587
588        let token = parser.get_token().unwrap();
589        assert_eq!(token, Token::Whitespace("\n\n".to_string()));
590        assert_eq!(parser.line(), 6);
591    }
592
593    #[test]
594    pub fn test_get_token_5() {
595        let str = r#"%s"Hello" %i"world""#;
596        let mut parser = Parser::new(str.to_string());
597
598        let token = parser.get_token().unwrap();
599        assert_eq!(token, Token::SString("Hello".to_string()));
600        assert_eq!(parser.pos(), 9);
601
602        let token = parser.get_token().unwrap();
603        assert_eq!(token, Token::Whitespace(" ".to_string()));
604
605        let token = parser.get_token().unwrap();
606        assert_eq!(token, Token::IString("world".to_string()));
607        assert_eq!(parser.pos(), 19);
608    }
609
610    #[test]
611    pub fn test_get_token_6() {
612        let str = "%x20 %b01010101  %d12345";
613        let mut parser = Parser::new(str.to_string());
614
615        let token = parser.get_token().unwrap();
616        assert_eq!(token, Token::NumberValue(32));
617        assert_eq!(parser.pos(), 4);
618
619        let token = parser.get_token().unwrap();
620        assert_eq!(token, Token::Whitespace(" ".to_string()));
621
622        let token = parser.get_token().unwrap();
623        assert_eq!(token, Token::NumberValue(0x55));
624        assert_eq!(parser.pos(), 15);
625
626        let token = parser.get_token().unwrap();
627        assert_eq!(token, Token::Whitespace("  ".to_string()));
628
629        let token = parser.get_token().unwrap();
630        assert_eq!(token, Token::NumberValue(12345));
631        assert_eq!(parser.pos(), 24);
632    }
633
634    #[test]
635    pub fn test_get_token_7() {
636        let str = "%x20-D7FF %xE000-FDCF";
637        let mut parser = Parser::new(str.to_string());
638
639        let token = parser.get_token().unwrap();
640        assert_eq!(token, Token::ValueRange((0x20, 0xd7ff)));
641        assert_eq!(parser.pos(), 9);
642
643        let token = parser.get_token().unwrap();
644        assert_eq!(token, Token::Whitespace(" ".to_string()));
645
646        let token = parser.get_token().unwrap();
647        assert_eq!(token, Token::ValueRange((0xe000, 0xfdcf)));
648        assert_eq!(parser.pos(), 21);
649    }
650
651    #[test]
652    pub fn test_get_token_8() {
653        let str = "%x20.21.22";
654        let mut parser = Parser::new(str.to_string());
655
656        let token = parser.get_token().unwrap();
657        assert_eq!(token, Token::ValueSequence(vec![0x20, 0x21, 0x22]));
658        assert_eq!(parser.pos(), 10);
659    }
660
661    #[test]
662    pub fn test_get_token_invalid_1() {
663        let str = "   !";
664        let mut parser = Parser::new(str.to_string());
665
666        let token = parser.get_token().unwrap();
667        assert_eq!(token, Token::Whitespace("   ".to_string()));
668
669        match parser.get_token() {
670            Err(AbnfParseError::TokenParseError) => { /* ok */ }
671            Err(err) => assert!(false, "{:?}", err),
672            _ => assert!(false),
673        }
674    }
675
676    #[test]
677    pub fn test_get_token_invalid_2() {
678        let str = "%x20.21-22";
679        let mut parser = Parser::new(str.to_string());
680
681        match parser.get_token() {
682            Err(AbnfParseError::ParseIntError(_)) => { /* ok */ }
683            Err(err) => assert!(false, "{:?}", err),
684            _ => assert!(false),
685        }
686    }
687
688    #[test]
689    pub fn test_parse_rule_1() {
690        // ABNF "rulelist" rule.
691        let str = r#"1*( rule / (*c-wsp c-nl) )"#;
692        let mut parser = Parser::new(str.to_string());
693        let rep = Repetition {
694            repeat: Some(Repeat {
695                min: Some(1),
696                max: None,
697            }),
698            element: Element::Selection(vec![
699                Repetition {
700                    repeat: None,
701                    element: Element::Rulename("rule".to_string()),
702                },
703                Repetition {
704                    repeat: None,
705                    element: Element::Sequence(vec![
706                        Repetition {
707                            repeat: Some(Repeat {
708                                min: None,
709                                max: None,
710                            }),
711                            element: Element::Rulename("c-wsp".to_string()),
712                        },
713                        Repetition {
714                            repeat: None,
715                            element: Element::Rulename("c-nl".to_string()),
716                        },
717                    ]),
718                },
719            ]),
720        };
721        if let Ok(r) = parser.parse_rule() {
722            assert_eq!(r, rep);
723        }
724    }
725
726    #[test]
727    pub fn test_parse_rule_2() {
728        // ABNF "rulename" rule.
729        let str = r#"ALPHA *(ALPHA / DIGIT / "-")"#;
730        let mut parser = Parser::new(str.to_string());
731        let rep = Repetition {
732            repeat: None,
733            element: Element::Sequence(vec![
734                Repetition {
735                    repeat: None,
736                    element: Element::Rulename("ALPHA".to_string()),
737                },
738                Repetition {
739                    repeat: Some(Repeat {
740                        min: None,
741                        max: None,
742                    }),
743                    element: Element::Selection(vec![
744                        Repetition {
745                            repeat: None,
746                            element: Element::Rulename("ALPHA".to_string()),
747                        },
748                        Repetition {
749                            repeat: None,
750                            element: Element::Rulename("DIGIT".to_string()),
751                        },
752                        Repetition {
753                            repeat: None,
754                            element: Element::IString("-".to_string()),
755                        },
756                    ]),
757                },
758            ]),
759        };
760        if let Ok(r) = parser.parse_rule() {
761            assert_eq!(r, rep);
762        }
763    }
764
765    #[test]
766    pub fn test_parse_rule_3() {
767        // ABNF "rule" rule.
768        let str = r#"rulename defined-as elements c-nl
769                                ; continues if next line starts
770                                ;  with white space"#;
771        let mut parser = Parser::new(str.to_string());
772        let rep = Repetition {
773            repeat: None,
774            element: Element::Sequence(vec![
775                Repetition {
776                    repeat: None,
777                    element: Element::Rulename("rulename".to_string()),
778                },
779                Repetition {
780                    repeat: None,
781                    element: Element::Rulename("defined-as".to_string()),
782                },
783                Repetition {
784                    repeat: None,
785                    element: Element::Rulename("elements".to_string()),
786                },
787                Repetition {
788                    repeat: None,
789                    element: Element::Rulename("c-nl".to_string()),
790                },
791            ]),
792        };
793        if let Ok(r) = parser.parse_rule() {
794            assert_eq!(r, rep);
795        }
796    }
797
798    #[test]
799    pub fn test_parse_rule_4() {
800        // ABNF "defined-as" rule.
801        let str = r#"*c-wsp ("=" / "=/") *c-wsp
802                                ; basic rules definition and
803                                ;  incremental alternatives"#;
804        let mut parser = Parser::new(str.to_string());
805        let rep = Repetition {
806            repeat: None,
807            element: Element::Sequence(vec![
808                Repetition {
809                    repeat: Some(Repeat {
810                        min: None,
811                        max: None,
812                    }),
813                    element: Element::Rulename("c-wsp".to_string()),
814                },
815                Repetition {
816                    repeat: None,
817                    element: Element::Selection(vec![
818                        Repetition {
819                            repeat: None,
820                            element: Element::IString("=".to_string()),
821                        },
822                        Repetition {
823                            repeat: None,
824                            element: Element::IString("=/".to_string()),
825                        },
826                    ]),
827                },
828                Repetition {
829                    repeat: Some(Repeat {
830                        min: None,
831                        max: None,
832                    }),
833                    element: Element::Rulename("c-wsp".to_string()),
834                },
835            ]),
836        };
837        if let Ok(r) = parser.parse_rule() {
838            assert_eq!(r, rep);
839        }
840    }
841
842    #[test]
843    pub fn test_parse_rule_5() {
844        // ABNF "char-val" rule.
845        let str = r#"DQUOTE *(%x20-21 / %x23-7E) DQUOTE
846                                ; quoted string of SP and VCHAR
847                                ;  without DQUOTE"#;
848        let mut parser = Parser::new(str.to_string());
849        let rep = Repetition {
850            repeat: None,
851            element: Element::Sequence(vec![
852                Repetition {
853                    repeat: None,
854                    element: Element::Rulename("DQUOTE".to_string()),
855                },
856                Repetition {
857                    repeat: Some(Repeat {
858                        min: None,
859                        max: None,
860                    }),
861                    element: Element::Selection(vec![
862                        Repetition {
863                            repeat: None,
864                            element: Element::ValueRange((32, 33)),
865                        },
866                        Repetition {
867                            repeat: None,
868                            element: Element::ValueRange((35, 126)),
869                        },
870                    ]),
871                },
872                Repetition {
873                    repeat: None,
874                    element: Element::Rulename("DQUOTE".to_string()),
875                },
876            ]),
877        };
878
879        if let Ok(r) = parser.parse_rule() {
880            assert_eq!(r, rep);
881        }
882    }
883
884    #[test]
885    pub fn test_parse_rule_6() {
886        // ABNF "group" rule.
887        let str = r#""(" *c-wsp alternation *c-wsp ")""#;
888        let mut parser = Parser::new(str.to_string());
889        let rep = Repetition {
890            repeat: None,
891            element: Element::Sequence(vec![
892                Repetition {
893                    repeat: None,
894                    element: Element::IString("(".to_string()),
895                },
896                Repetition {
897                    repeat: Some(Repeat {
898                        min: None,
899                        max: None,
900                    }),
901                    element: Element::Rulename("c-wsp".to_string()),
902                },
903                Repetition {
904                    repeat: None,
905                    element: Element::Rulename("alternation".to_string()),
906                },
907                Repetition {
908                    repeat: Some(Repeat {
909                        min: None,
910                        max: None,
911                    }),
912                    element: Element::Rulename("c-wsp".to_string()),
913                },
914                Repetition {
915                    repeat: None,
916                    element: Element::IString(")".to_string()),
917                },
918            ]),
919        };
920
921        if let Ok(r) = parser.parse_rule() {
922            assert_eq!(r, rep);
923        }
924    }
925
926    #[test]
927    pub fn test_parse_rule_7() {
928        // ABNF "dec-val" rule.
929        let str = r#""d" 1*DIGIT
930                           [ 1*("." 1*DIGIT) / ("-" 1*DIGIT) ]"#;
931        let mut parser = Parser::new(str.to_string());
932        let rep = Repetition {
933            repeat: None,
934            element: Element::Sequence(vec![
935                Repetition {
936                    repeat: None,
937                    element: Element::IString("d".to_string()),
938                },
939                Repetition {
940                    repeat: Some(Repeat {
941                        min: Some(1),
942                        max: None,
943                    }),
944                    element: Element::Rulename("DIGIT".to_string()),
945                },
946                Repetition {
947                    repeat: Some(Repeat {
948                        min: Some(0),
949                        max: Some(1),
950                    }),
951                    element: Element::Selection(vec![
952                        Repetition {
953                            repeat: Some(Repeat {
954                                min: Some(1),
955                                max: None,
956                            }),
957                            element: Element::Sequence(vec![
958                                Repetition {
959                                    repeat: None,
960                                    element: Element::IString(".".to_string()),
961                                },
962                                Repetition {
963                                    repeat: Some(Repeat {
964                                        min: Some(1),
965                                        max: None,
966                                    }),
967                                    element: Element::Rulename("DIGIT".to_string()),
968                                },
969                            ]),
970                        },
971                        Repetition {
972                            repeat: None,
973                            element: Element::Sequence(vec![
974                                Repetition {
975                                    repeat: None,
976                                    element: Element::IString("-".to_string()),
977                                },
978                                Repetition {
979                                    repeat: Some(Repeat {
980                                        min: Some(1),
981                                        max: None,
982                                    }),
983                                    element: Element::Rulename("DIGIT".to_string()),
984                                },
985                            ]),
986                        },
987                    ]),
988                },
989            ]),
990        };
991
992        if let Ok(r) = parser.parse_rule() {
993            assert_eq!(r, rep);
994        }
995    }
996
997    // TODO more parse tests.
998
999    #[test]
1000    pub fn test_parse_1() {
1001        let str = r#"   "Hello world""#;
1002        let mut parser = Parser::new(str.to_string());
1003        match parser.parse() {
1004            Err(AbnfParseError::ExpectRulename(_)) => {}
1005            Err(e) => assert!(false, "Unexpected error {:?}", e),
1006            Ok(_) => assert!(false, "Not OK"),
1007        }
1008    }
1009
1010    #[test]
1011    pub fn test_parse_6() {
1012        let str = r#"
1013            ruleset  = alt1 / alt2
1014
1015            ruleset =/ alt3
1016
1017            ruleset =/ alt4 / alt5
1018        "#;
1019        let mut parser = Parser::new(str.to_string());
1020        match parser.parse() {
1021            Err(e) => assert!(false, "error {:?}", e),
1022            Ok(r) => {
1023                let rep = r.get("ruleset").unwrap();
1024                assert_eq!(
1025                    rep,
1026                    &Repetition {
1027                        repeat: None,
1028                        element: Element::Selection(vec![
1029                            Repetition {
1030                                repeat: None,
1031                                element: Element::Rulename("alt1".to_string())
1032                            },
1033                            Repetition {
1034                                repeat: None,
1035                                element: Element::Rulename("alt2".to_string())
1036                            },
1037                            Repetition {
1038                                repeat: None,
1039                                element: Element::Rulename("alt3".to_string())
1040                            },
1041                            Repetition {
1042                                repeat: None,
1043                                element: Element::Rulename("alt4".to_string())
1044                            },
1045                            Repetition {
1046                                repeat: None,
1047                                element: Element::Rulename("alt5".to_string())
1048                            }
1049                        ])
1050                    }
1051                )
1052            }
1053        }
1054    }
1055
1056    #[test]
1057    pub fn test_parse_7() {
1058        let str = r#"
1059            ruleset  = alt1 
1060
1061            ruleset =/ alt2 / alt3
1062
1063            ruleset =/ alt4 / alt5
1064        "#;
1065        let mut parser = Parser::new(str.to_string());
1066        match parser.parse() {
1067            Err(e) => assert!(false, "error {:?}", e),
1068            Ok(r) => {
1069                let rep = r.get("ruleset").unwrap();
1070                assert_eq!(
1071                    rep,
1072                    &Repetition {
1073                        repeat: None,
1074                        element: Element::Selection(vec![
1075                            Repetition {
1076                                repeat: None,
1077                                element: Element::Rulename("alt1".to_string())
1078                            },
1079                            Repetition {
1080                                repeat: None,
1081                                element: Element::Rulename("alt2".to_string())
1082                            },
1083                            Repetition {
1084                                repeat: None,
1085                                element: Element::Rulename("alt3".to_string())
1086                            },
1087                            Repetition {
1088                                repeat: None,
1089                                element: Element::Rulename("alt4".to_string())
1090                            },
1091                            Repetition {
1092                                repeat: None,
1093                                element: Element::Rulename("alt5".to_string())
1094                            }
1095                        ])
1096                    }
1097                )
1098            }
1099        }
1100    }
1101}