1use 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#[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
40pub struct Parser {
42 input: String,
44 pos: Cell<usize>,
46 line: Cell<usize>,
48}
49
50impl Parser {
51 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 pub fn input(&self) -> &str {
62 &self.input[self.pos.get()..]
63 }
64
65 pub fn input_len(&self) -> usize {
67 self.input.len() - self.pos.get()
68 }
69
70 pub fn pos(&self) -> usize {
72 self.pos.get()
73 }
74
75 pub fn pos_set(&mut self, pos: usize) {
77 self.pos.set(self.pos.get() + pos);
78 }
79
80 pub fn line(&self) -> usize {
82 self.line.get()
83 }
84
85 pub fn line_add(&self, len: usize) {
87 self.line.set(self.line.get() + len);
88 }
89
90 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 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 loop {
283 let token = self.get_token()?;
284 match token {
285 Token::Whitespace(_) | Token::Comment(_) => {
286 }
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 loop {
302 let token = self.get_token()?;
303 match token {
304 Token::Whitespace(_) | Token::Comment(_) => {
305 }
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 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 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
455fn 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
466pub 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) => { }
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(_)) => { }
683 Err(err) => assert!(false, "{:?}", err),
684 _ => assert!(false),
685 }
686 }
687
688 #[test]
689 pub fn test_parse_rule_1() {
690 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 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 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 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 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 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 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 #[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}