1use crate::ast::*;
4use std::fmt;
5
6#[derive(Debug, Clone, PartialEq)]
7pub struct ParseError {
8 pub message: String,
9 pub line: usize,
10 pub column: usize,
11}
12
13impl fmt::Display for ParseError {
14 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15 write!(
16 f,
17 "Parse error at {}:{}: {}",
18 self.line, self.column, self.message
19 )
20 }
21}
22
23impl std::error::Error for ParseError {}
24
25type Result<T> = std::result::Result<T, ParseError>;
26
27const TYPE_CONSTRUCTORS: &[&str] = &["SEQUENCE", "SET", "CHOICE", "OF"];
32
33const FIELD_MODIFIERS: &[&str] = &["OPTIONAL", "DEFAULT"];
35
36const PRIMITIVE_TYPES: &[&str] = &[
38 "INTEGER",
39 "BOOLEAN",
40 "OCTET",
41 "STRING",
42 "BIT",
43 "OBJECT",
44 "IDENTIFIER",
45 "NULL",
46 "REAL",
47 "ENUMERATED",
48];
49
50const STRING_TYPES: &[&str] = &[
53 "UTF8String",
54 "PrintableString",
55 "IA5String",
56 "TeletexString",
57 "T61String",
58 "BMPString",
59 "UniversalString",
60 "GeneralString",
61 "GraphicString",
62 "NumericString",
63 "ObjectDescriptor",
64 "VideotexString",
65 "VisibleString",
66 "ISO646String",
67];
68
69const TIME_TYPES: &[&str] = &[
71 "UTCTime",
72 "GeneralizedTime",
73 "DATE",
74 "TIME",
75 "TIME-OF-DAY",
76 "DATE-TIME",
77 "DURATION",
78];
79
80const TAGGING_KEYWORDS: &[&str] = &[
82 "EXPLICIT",
83 "IMPLICIT",
84 "AUTOMATIC",
85 "TAGS",
86 "UNIVERSAL",
87 "APPLICATION",
88 "PRIVATE",
89 "CONTEXT",
90 "IMPLIED",
91];
92
93const MODULE_KEYWORDS: &[&str] = &["BEGIN", "END", "DEFINITIONS"];
95
96const CONSTRAINT_KEYWORDS: &[&str] = &[
98 "SIZE",
99 "MIN",
100 "MAX",
101 "FROM",
102 "PATTERN",
103 "CONTAINING",
104 "WITH",
105 "COMPONENTS",
106];
107
108const SET_OPERATIONS: &[&str] = &["ALL", "EXCEPT", "INCLUDES", "INTERSECTION", "UNION"];
110
111const IMPORT_EXPORT: &[&str] = &["IMPORTS", "EXPORTS"];
113
114const SPECIAL_KEYWORDS: &[&str] = &[
116 "ANY",
117 "DEFINED",
118 "BY",
119 "ABSENT",
120 "PRESENT",
121 "TRUE",
122 "FALSE",
123 "EXTENSIBILITY",
124 "ENCODED",
125 "PLUS-INFINITY",
126 "MINUS-INFINITY",
127 "NOT-A-NUMBER",
128];
129
130const CLASS_KEYWORDS: &[&str] = &[
132 "CLASS",
133 "UNIQUE",
134 "SYNTAX",
135 "TYPE-IDENTIFIER",
136 "ABSTRACT-SYNTAX",
137];
138
139const ADDITIONAL_TYPES: &[&str] = &[
141 "EXTERNAL",
142 "EMBEDDED",
143 "PDV",
144 "CHARACTER",
145 "RELATIVE-OID",
146 "OID-IRI",
147 "RELATIVE-OID-IRI",
148];
149
150fn is_asn1_keyword(s: &str) -> bool {
152 TYPE_CONSTRUCTORS.contains(&s)
153 || FIELD_MODIFIERS.contains(&s)
154 || PRIMITIVE_TYPES.contains(&s)
155 || STRING_TYPES.contains(&s)
156 || TIME_TYPES.contains(&s)
157 || TAGGING_KEYWORDS.contains(&s)
158 || MODULE_KEYWORDS.contains(&s)
159 || CONSTRAINT_KEYWORDS.contains(&s)
160 || SET_OPERATIONS.contains(&s)
161 || IMPORT_EXPORT.contains(&s)
162 || SPECIAL_KEYWORDS.contains(&s)
163 || CLASS_KEYWORDS.contains(&s)
164 || ADDITIONAL_TYPES.contains(&s)
165}
166
167fn is_builtin_type_keyword(s: &str) -> bool {
169 STRING_TYPES.contains(&s) || TIME_TYPES.contains(&s) || ADDITIONAL_TYPES.contains(&s)
170}
171
172#[derive(Clone)]
174struct Lexer {
175 input: Vec<char>,
176 pos: usize,
177 line: usize,
178 column: usize,
179}
180
181#[derive(Debug, Clone, PartialEq)]
182enum Token {
183 Identifier(String),
184 Number(u32),
185 Keyword(String),
186 Symbol(String),
187 Eof,
188}
189
190impl Lexer {
191 fn new(input: &str) -> Self {
192 Self {
193 input: input.chars().collect(),
194 pos: 0,
195 line: 1,
196 column: 1,
197 }
198 }
199
200 fn current(&self) -> Option<char> {
201 self.input.get(self.pos).copied()
202 }
203
204 fn advance(&mut self) -> Option<char> {
205 if let Some(ch) = self.current() {
206 self.pos += 1;
207 if ch == '\n' {
208 self.line += 1;
209 self.column = 1;
210 } else {
211 self.column += 1;
212 }
213 Some(ch)
214 } else {
215 None
216 }
217 }
218
219 fn skip_whitespace(&mut self) {
220 while let Some(ch) = self.current() {
221 if ch.is_whitespace() {
222 self.advance();
223 } else if ch == '-' && self.peek(1) == Some('-') {
224 while let Some(ch) = self.current() {
226 self.advance();
227 if ch == '\n' {
228 break;
229 }
230 }
231 } else {
232 break;
233 }
234 }
235 }
236
237 fn peek(&self, offset: usize) -> Option<char> {
238 self.input.get(self.pos + offset).copied()
239 }
240
241 fn next_token(&mut self) -> Result<Token> {
242 self.skip_whitespace();
243
244 let ch = match self.current() {
245 Some(ch) => ch,
246 None => return Ok(Token::Eof),
247 };
248
249 if ch == '"' {
251 self.advance(); let mut string = String::new();
253 while let Some(ch) = self.current() {
254 if ch == '"' {
255 self.advance(); break;
257 } else if ch == '\\' {
258 self.advance();
260 if let Some(escaped) = self.current() {
261 match escaped {
262 'n' => string.push('\n'),
263 't' => string.push('\t'),
264 'r' => string.push('\r'),
265 '\\' => string.push('\\'),
266 '"' => string.push('"'),
267 _ => string.push(escaped),
268 }
269 self.advance();
270 }
271 } else {
272 string.push(ch);
273 self.advance();
274 }
275 }
276 return Ok(Token::Identifier(string)); }
278
279 if ch.is_ascii_digit() {
281 let mut num = String::new();
282 while let Some(ch) = self.current() {
283 if ch.is_ascii_digit() {
284 num.push(ch);
285 self.advance();
286 } else {
287 break;
288 }
289 }
290 return Ok(Token::Number(num.parse().unwrap()));
291 }
292
293 if ch == '&' && self.peek(1).is_some_and(|c| c.is_alphabetic()) {
296 self.advance(); let mut ident = String::from("&");
298 while let Some(ch) = self.current() {
299 if ch.is_alphanumeric() || ch == '-' {
300 ident.push(ch);
301 self.advance();
302 } else {
303 break;
304 }
305 }
306 return Ok(Token::Identifier(ident));
307 }
308
309 if ch.is_alphabetic() {
311 let mut ident = String::new();
312 while let Some(ch) = self.current() {
313 if ch.is_alphanumeric() || ch == '-' {
314 ident.push(ch);
315 self.advance();
316 } else {
317 break;
318 }
319 }
320
321 if is_asn1_keyword(&ident) {
324 return Ok(Token::Keyword(ident));
325 }
326
327 return Ok(Token::Identifier(ident));
328 }
329
330 if ch == ':' && self.peek(1) == Some(':') && self.peek(2) == Some('=') {
332 self.advance();
333 self.advance();
334 self.advance();
335 return Ok(Token::Symbol("::=".to_string()));
336 }
337
338 if ch == '.' && self.peek(1) == Some('.') && self.peek(2) == Some('.') {
339 self.advance();
340 self.advance();
341 self.advance();
342 return Ok(Token::Symbol("...".to_string()));
343 }
344
345 if ch == '.' && self.peek(1) == Some('.') {
346 self.advance();
347 self.advance();
348 return Ok(Token::Symbol("..".to_string()));
349 }
350
351 if ch == '-' && self.peek(1) != Some('-') {
353 self.advance();
354 return Ok(Token::Symbol("-".to_string()));
355 }
356
357 if matches!(
359 ch,
360 '{' | '}' | '[' | ']' | '(' | ')' | ',' | ':' | '|' | '^' | '@' | ';'
361 ) {
362 self.advance();
363 return Ok(Token::Symbol(ch.to_string()));
364 }
365
366 Err(ParseError {
367 message: format!("Unexpected character: {}", ch),
368 line: self.line,
369 column: self.column,
370 })
371 }
372}
373
374pub struct Parser {
376 lexer: Lexer,
377 current: Token,
378 default_tagging: Tagging,
382}
383
384impl Parser {
385 pub fn new(input: &str) -> Result<Self> {
386 let mut lexer = Lexer::new(input);
387 let current = lexer.next_token()?;
388 Ok(Self {
389 lexer,
390 current,
391 default_tagging: Tagging::Explicit,
392 })
393 }
394
395 fn advance(&mut self) -> Result<()> {
396 self.current = self.lexer.next_token()?;
397 Ok(())
398 }
399
400 fn expect_keyword(&mut self, keyword: &str) -> Result<()> {
401 if let Token::Keyword(kw) = &self.current {
402 if kw == keyword {
403 self.advance()?;
404 return Ok(());
405 }
406 }
407 Err(ParseError {
408 message: format!("Expected keyword '{}', got {:?}", keyword, self.current),
409 line: self.lexer.line,
410 column: self.lexer.column,
411 })
412 }
413
414 fn expect_symbol(&mut self, symbol: &str) -> Result<()> {
415 if let Token::Symbol(sym) = &self.current {
416 if sym == symbol {
417 self.advance()?;
418 return Ok(());
419 }
420 }
421 Err(ParseError {
422 message: format!("Expected symbol '{}', got {:?}", symbol, self.current),
423 line: self.lexer.line,
424 column: self.lexer.column,
425 })
426 }
427
428 fn expect_identifier(&mut self) -> Result<String> {
429 if let Token::Identifier(name) = &self.current {
430 let result = name.clone();
431 self.advance()?;
432 return Ok(result);
433 }
434 Err(ParseError {
435 message: format!("Expected identifier, got {:?}", self.current),
436 line: self.lexer.line,
437 column: self.lexer.column,
438 })
439 }
440
441 fn parse_size_constraint(&mut self) -> Result<Option<SizeConstraint>> {
443 if !matches!(self.current, Token::Symbol(ref s) if s == "(") {
444 return Ok(None);
445 }
446
447 self.advance()?; if !matches!(self.current, Token::Keyword(ref kw) if kw == "SIZE") {
451 while !matches!(self.current, Token::Symbol(ref s) if s == ")") {
453 if matches!(self.current, Token::Eof) {
454 break;
455 }
456 self.advance()?;
457 }
458 if matches!(self.current, Token::Symbol(ref s) if s == ")") {
459 self.advance()?;
460 }
461 return Ok(None);
462 }
463
464 self.advance()?; self.expect_symbol("(")?;
466
467 let min = if let Token::Number(n) = self.current {
469 let val = n;
470 self.advance()?;
471 Some(val as u64)
472 } else {
473 None
474 };
475
476 let constraint = if matches!(self.current, Token::Symbol(ref s) if s == "..") {
477 self.advance()?;
478 let max = if let Token::Number(n) = self.current {
479 let val = n;
480 self.advance()?;
481 Some(val as u64)
482 } else {
483 None
484 };
485 SizeConstraint::Range(min, max)
486 } else if let Some(size) = min {
487 SizeConstraint::Fixed(size)
488 } else {
489 return Ok(None);
490 };
491
492 self.expect_symbol(")")?; self.expect_symbol(")")?; Ok(Some(constraint))
496 }
497
498 fn parse_integer_value(&mut self) -> Result<Option<i64>> {
500 let negative = if matches!(self.current, Token::Symbol(ref s) if s == "-") {
502 self.advance()?;
503 true
504 } else {
505 false
506 };
507
508 if let Token::Number(n) = self.current {
509 let val = if negative { -(n as i64) } else { n as i64 };
510 self.advance()?;
511 Ok(Some(val))
512 } else {
513 Ok(None)
514 }
515 }
516
517 fn parse_constraint_value(&mut self) -> Result<ConstraintValue> {
519 if matches!(self.current, Token::Keyword(ref kw) if kw == "MIN") {
521 self.advance()?;
522 return Ok(ConstraintValue::Min);
523 }
524
525 if matches!(self.current, Token::Keyword(ref kw) if kw == "MAX") {
527 self.advance()?;
528 return Ok(ConstraintValue::Max);
529 }
530
531 if let Token::Identifier(ref name) = self.current {
533 let name = name.clone();
534 self.advance()?;
535 return Ok(ConstraintValue::NamedValue(name));
536 }
537
538 if let Some(val) = self.parse_integer_value()? {
540 return Ok(ConstraintValue::Integer(val));
541 }
542
543 Err(ParseError {
544 message: "Expected constraint value (integer, MIN, MAX, or identifier)".to_string(),
545 line: self.lexer.line,
546 column: self.lexer.column,
547 })
548 }
549
550 fn parse_subtype_constraint(&mut self) -> Result<SubtypeConstraint> {
552 let first = self.parse_single_constraint()?;
554
555 let mut elements = vec![first];
557 let mut is_union = false;
558 let mut is_intersection = false;
559
560 while matches!(self.current, Token::Symbol(ref s) if s == "|" || s == "^") {
561 let op = if let Token::Symbol(ref s) = self.current {
562 s.clone()
563 } else {
564 unreachable!()
565 };
566
567 if op == "|" {
568 is_union = true;
569 } else if op == "^" {
570 is_intersection = true;
571 }
572
573 self.advance()?; elements.push(self.parse_single_constraint()?);
575 }
576
577 if is_union && is_intersection {
579 return Err(ParseError {
580 message: "Cannot mix union (|) and intersection (^) operators without parentheses"
581 .to_string(),
582 line: self.lexer.line,
583 column: self.lexer.column,
584 });
585 }
586
587 if is_union {
588 Ok(SubtypeConstraint::Union(elements))
589 } else if is_intersection {
590 Ok(SubtypeConstraint::Intersection(elements))
591 } else {
592 Ok(elements.into_iter().next().unwrap())
593 }
594 }
595
596 fn parse_single_constraint(&mut self) -> Result<SubtypeConstraint> {
598 if matches!(self.current, Token::Keyword(ref kw) if kw == "ALL") {
600 self.advance()?;
601 self.expect_keyword("EXCEPT")?;
602 let inner = self.parse_single_constraint()?;
603 return Ok(SubtypeConstraint::Complement(Box::new(inner)));
604 }
605
606 if matches!(self.current, Token::Symbol(ref s) if s == "(") {
608 self.advance()?; let constraint = self.parse_subtype_constraint()?;
610 self.expect_symbol(")")?;
611 return Ok(constraint);
612 }
613
614 let first_value = self.parse_constraint_value()?;
616
617 if matches!(self.current, Token::Symbol(ref s) if s == "..") {
619 self.advance()?; let second_value = self.parse_constraint_value()?;
621 return Ok(SubtypeConstraint::ValueRange {
622 min: first_value,
623 max: second_value,
624 });
625 }
626
627 Ok(SubtypeConstraint::SingleValue(first_value))
629 }
630
631 fn parse_permitted_alphabet(&mut self) -> Result<SubtypeConstraint> {
633 self.expect_keyword("FROM")?;
634 self.expect_symbol("(")?;
635
636 let mut ranges = Vec::new();
637
638 loop {
639 if let Token::Identifier(ref s) = self.current {
641 let chars: Vec<char> = s.chars().collect();
643 if chars.len() == 1 {
644 let ch = chars[0];
645 self.advance()?;
646
647 if matches!(self.current, Token::Symbol(ref sym) if sym == "..") {
649 self.advance()?; if let Token::Identifier(ref end_s) = self.current {
653 let end_chars: Vec<char> = end_s.chars().collect();
654 if end_chars.len() == 1 {
655 ranges.push(CharRange {
656 min: ch,
657 max: end_chars[0],
658 });
659 self.advance()?;
660 }
661 }
662 } else {
663 ranges.push(CharRange { min: ch, max: ch });
665 }
666 }
667 }
668
669 if matches!(self.current, Token::Symbol(ref s) if s == "|") {
671 self.advance()?; } else {
673 break;
674 }
675 }
676
677 self.expect_symbol(")")?;
678 Ok(SubtypeConstraint::PermittedAlphabet(ranges))
679 }
680
681 fn parse_pattern(&mut self) -> Result<SubtypeConstraint> {
683 self.expect_keyword("PATTERN")?;
684
685 if let Token::Identifier(ref pattern) = self.current {
687 let pattern_str = pattern.clone();
688 self.advance()?;
689 Ok(SubtypeConstraint::Pattern(pattern_str))
690 } else {
691 Err(ParseError {
692 message: "Expected pattern string after PATTERN keyword".to_string(),
693 line: self.lexer.line,
694 column: self.lexer.column,
695 })
696 }
697 }
698
699 fn parse_default_value(&mut self) -> Result<String> {
701 let value = match &self.current {
702 Token::Number(n) => {
703 let val = n.to_string();
704 self.advance()?;
705 val
706 }
707 Token::Symbol(s) if s == "-" => {
708 self.advance()?;
710 if let Token::Number(n) = self.current {
711 let val = format!("-{}", n);
712 self.advance()?;
713 val
714 } else {
715 return Err(ParseError {
716 message: "Expected number after '-'".to_string(),
717 line: self.lexer.line,
718 column: self.lexer.column,
719 });
720 }
721 }
722 Token::Keyword(kw) if kw == "TRUE" => {
723 self.advance()?;
724 "true".to_string()
725 }
726 Token::Keyword(kw) if kw == "FALSE" => {
727 self.advance()?;
728 "false".to_string()
729 }
730 Token::Identifier(s) => {
731 let val = s.clone();
733 self.advance()?;
734 val
737 }
738 _ => {
739 return Err(ParseError {
740 message: format!("Unexpected token in DEFAULT value: {:?}", self.current),
741 line: self.lexer.line,
742 column: self.lexer.column,
743 });
744 }
745 };
746
747 Ok(value)
748 }
749
750 fn parse_string_type(&mut self, base_type: Type) -> Result<Type> {
753 self.advance()?;
754
755 if let Some(constraint) = self.parse_string_constraint()? {
757 return Ok(Type::Constrained {
758 base_type: Box::new(base_type),
759 constraint: Constraint {
760 spec: ConstraintSpec::Subtype(constraint),
761 exception: None,
762 },
763 });
764 }
765
766 Ok(base_type)
767 }
768
769 fn parse_string_constraint(&mut self) -> Result<Option<SubtypeConstraint>> {
772 if !matches!(self.current, Token::Symbol(ref s) if s == "(") {
773 return Ok(None);
774 }
775
776 self.advance()?; let mut constraints = Vec::new();
780
781 if let Some(constraint) = self.parse_single_string_constraint()? {
783 constraints.push(constraint);
784 }
785
786 while !matches!(self.current, Token::Symbol(ref s) if s == ")") {
789 if matches!(self.current, Token::Eof) {
790 break;
791 }
792
793 if let Some(constraint) = self.parse_single_string_constraint()? {
795 constraints.push(constraint);
796 } else {
797 break;
799 }
800 }
801
802 self.expect_symbol(")")?; match constraints.len() {
806 0 => Ok(None),
807 1 => Ok(Some(constraints.into_iter().next().unwrap())),
808 _ => {
809 Ok(Some(SubtypeConstraint::Intersection(constraints)))
811 }
812 }
813 }
814
815 fn parse_single_string_constraint(&mut self) -> Result<Option<SubtypeConstraint>> {
817 if matches!(self.current, Token::Keyword(ref kw) if kw == "SIZE") {
819 self.advance()?; self.expect_symbol("(")?;
821
822 let size_constraint = self.parse_subtype_constraint()?;
824
825 self.expect_symbol(")")?; return Ok(Some(SubtypeConstraint::SizeConstraint(Box::new(
829 size_constraint,
830 ))));
831 }
832
833 if matches!(self.current, Token::Keyword(ref kw) if kw == "FROM") {
835 let constraint = self.parse_permitted_alphabet()?;
836 return Ok(Some(constraint));
838 }
839
840 if matches!(self.current, Token::Keyword(ref kw) if kw == "PATTERN") {
842 let constraint = self.parse_pattern()?;
843 return Ok(Some(constraint));
845 }
846
847 if matches!(self.current, Token::Keyword(ref kw) if kw == "CONTAINING") {
849 self.advance()?; let contained_type = self.parse_type()?;
851 return Ok(Some(SubtypeConstraint::ContainedSubtype(Box::new(
853 contained_type,
854 ))));
855 }
856
857 Ok(None)
858 }
859
860 fn parse_exports(&mut self) -> Result<Vec<String>> {
863 let mut exports = Vec::new();
864
865 if !matches!(self.current, Token::Keyword(ref kw) if kw == "EXPORTS") {
867 return Ok(exports);
868 }
869
870 self.advance()?; if matches!(self.current, Token::Keyword(ref kw) if kw == "ALL") {
874 self.advance()?; if matches!(self.current, Token::Symbol(ref s) if s == ";") {
876 self.advance()?; }
878 return Ok(exports);
881 }
882
883 loop {
885 if matches!(self.current, Token::Symbol(ref s) if s == ";") {
886 self.advance()?; break;
888 }
889
890 if matches!(self.current, Token::Eof)
891 || matches!(self.current, Token::Keyword(ref kw) if kw == "IMPORTS" || kw == "END")
892 {
893 break;
895 }
896
897 let name = self.expect_identifier()?;
898 exports.push(name);
899
900 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
902 self.advance()?; }
904 }
905
906 Ok(exports)
907 }
908
909 fn parse_imports(&mut self) -> Result<Vec<Import>> {
912 let mut imports = Vec::new();
913
914 if !matches!(self.current, Token::Keyword(ref kw) if kw == "IMPORTS") {
916 return Ok(imports);
917 }
918
919 self.advance()?; loop {
923 if matches!(self.current, Token::Symbol(ref s) if s == ";") {
924 self.advance()?; break;
926 }
927
928 if matches!(self.current, Token::Eof)
929 || matches!(self.current, Token::Keyword(ref kw) if kw == "END")
930 {
931 break;
933 }
934
935 let mut symbols = Vec::new();
937 loop {
938 if matches!(self.current, Token::Keyword(ref kw) if kw == "FROM") {
939 break;
940 }
941
942 let name = self.expect_identifier()?;
943
944 if matches!(self.current, Token::Symbol(ref s) if s == "{") {
947 self.skip_balanced_braces()?;
948 }
949
950 symbols.push(name);
951
952 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
954 self.advance()?; } else {
956 break;
957 }
958 }
959
960 self.expect_keyword("FROM")?;
962
963 let module_name = self.expect_identifier()?;
965
966 if matches!(self.current, Token::Symbol(ref s) if s == "{") {
969 self.skip_balanced_braces()?;
970 }
971
972 imports.push(Import {
973 symbols,
974 module_name,
975 });
976
977 if matches!(self.current, Token::Symbol(ref s) if s == ";") {
979 self.advance()?; break;
981 }
982
983 if matches!(self.current, Token::Eof)
985 || matches!(self.current, Token::Keyword(ref kw) if kw == "END")
986 || !matches!(self.current, Token::Identifier(_))
987 {
988 break;
989 }
990 }
991
992 Ok(imports)
993 }
994
995 pub fn parse_module(&mut self) -> Result<Module> {
997 let name = self.expect_identifier()?;
998
999 let oid = if let Token::Symbol(ref sym) = self.current {
1001 if sym == "{" {
1002 Some(self.parse_module_oid()?)
1003 } else {
1004 None
1005 }
1006 } else {
1007 None
1008 };
1009
1010 self.expect_keyword("DEFINITIONS")?;
1011
1012 let tagging_mode = if let Token::Keyword(ref kw) = self.current {
1014 match kw.as_str() {
1015 "EXPLICIT" => {
1016 self.advance()?;
1017 self.expect_keyword("TAGS")?;
1018 Some(crate::ast::TaggingMode::Explicit)
1019 }
1020 "IMPLICIT" => {
1021 self.advance()?;
1022 self.expect_keyword("TAGS")?;
1023 Some(crate::ast::TaggingMode::Implicit)
1024 }
1025 "AUTOMATIC" => {
1026 self.advance()?;
1027 self.expect_keyword("TAGS")?;
1028 Some(crate::ast::TaggingMode::Automatic)
1029 }
1030 _ => None,
1031 }
1032 } else {
1033 None
1034 };
1035
1036 self.default_tagging = match &tagging_mode {
1040 Some(crate::ast::TaggingMode::Implicit) | Some(crate::ast::TaggingMode::Automatic) => {
1041 Tagging::Implicit
1042 }
1043 _ => Tagging::Explicit,
1044 };
1045
1046 self.expect_symbol("::=")?;
1047 self.expect_keyword("BEGIN")?;
1048
1049 let exports = self.parse_exports()?;
1051
1052 let imports = self.parse_imports()?;
1054
1055 let mut definitions = Vec::new();
1057 let mut values = Vec::new();
1058 while !matches!(self.current, Token::Keyword(ref kw) if kw == "END") {
1059 if matches!(self.current, Token::Eof) {
1060 break;
1061 }
1062 if let Some(value_assignment) = self.try_parse_value_assignment()? {
1067 values.push(value_assignment);
1068 } else if self.try_skip_ioc_assignment()? {
1069 } else {
1071 definitions.push(self.parse_definition()?);
1072 }
1073 }
1074
1075 if matches!(self.current, Token::Keyword(ref kw) if kw == "END") {
1076 self.advance()?;
1077 }
1078
1079 Ok(Module {
1080 name,
1081 oid,
1082 tagging_mode,
1083 imports,
1084 exports,
1085 definitions,
1086 values,
1087 })
1088 }
1089
1090 fn parse_module_oid(&mut self) -> Result<Vec<String>> {
1093 self.expect_symbol("{")?;
1094 let mut oid_parts = Vec::new();
1095
1096 while !matches!(self.current, Token::Symbol(ref sym) if sym == "}") {
1098 match &self.current {
1099 Token::Identifier(id) => {
1100 oid_parts.push(id.clone());
1101 self.advance()?;
1102
1103 if let Token::Symbol(ref sym) = self.current {
1105 if sym == "(" {
1106 self.advance()?;
1107 if let Token::Number(n) = self.current {
1108 oid_parts.push(n.to_string());
1109 self.advance()?;
1110 }
1111 self.expect_symbol(")")?;
1112 }
1113 }
1114 }
1115 Token::Number(n) => {
1116 oid_parts.push(n.to_string());
1117 self.advance()?;
1118 }
1119 Token::Eof => {
1120 return Err(ParseError {
1121 message: "Unexpected end of input in module OID".to_string(),
1122 line: self.lexer.line,
1123 column: self.lexer.column,
1124 });
1125 }
1126 _ => {
1127 self.advance()?;
1129 }
1130 }
1131 }
1132
1133 self.expect_symbol("}")?;
1134 Ok(oid_parts)
1135 }
1136
1137 fn parse_definition(&mut self) -> Result<Definition> {
1138 let name = self.expect_identifier()?;
1139 self.expect_symbol("::=")?;
1140 let ty = self.parse_type()?;
1141
1142 Ok(Definition { name, ty })
1143 }
1144
1145 fn try_parse_value_assignment(&mut self) -> Result<Option<crate::ast::ValueAssignment>> {
1148 let is_value_assignment = if let Token::Identifier(_) = &self.current {
1156 matches!(self.peek_next_token(), Token::Keyword(ref kw)
1158 if kw == "OBJECT" || kw == "INTEGER" || kw == "BOOLEAN")
1159 } else {
1160 false
1161 };
1162
1163 if !is_value_assignment {
1164 return Ok(None);
1165 }
1166
1167 let name = self.expect_identifier()?;
1169 let ty = self.parse_type()?;
1170 self.expect_symbol("::=")?;
1171 let value = self.parse_value(&ty)?;
1172
1173 Ok(Some(crate::ast::ValueAssignment { name, ty, value }))
1174 }
1175
1176 fn try_skip_ioc_assignment(&mut self) -> Result<bool> {
1189 let is_ioc = if let Token::Identifier(_) = &self.current {
1192 matches!(self.peek_next_token(), Token::Identifier(_))
1193 } else {
1194 false
1195 };
1196
1197 if !is_ioc {
1198 return Ok(false);
1199 }
1200
1201 self.advance()?; self.advance()?; if !matches!(self.current, Token::Symbol(ref s) if s == "::=") {
1206 return Err(ParseError {
1207 message: format!("Expected '::=' in IOC assignment, got {:?}", self.current),
1208 line: self.lexer.line,
1209 column: self.lexer.column,
1210 });
1211 }
1212 self.advance()?; if matches!(self.current, Token::Symbol(ref s) if s == "{") {
1215 self.skip_balanced_braces()?;
1216 } else {
1217 self.advance()?;
1219 }
1220
1221 Ok(true)
1222 }
1223
1224 fn peek_next_token(&mut self) -> Token {
1226 let saved_lexer = self.lexer.clone();
1228 let saved_current = self.current.clone();
1229
1230 let _ = self.advance();
1232 let next = self.current.clone();
1233
1234 self.lexer = saved_lexer;
1236 self.current = saved_current;
1237
1238 next
1239 }
1240
1241 fn parse_value(&mut self, ty: &Type) -> Result<crate::ast::Value> {
1243 match ty {
1244 Type::ObjectIdentifier => {
1245 self.expect_symbol("{")?;
1247 let mut components = Vec::new();
1248
1249 while !matches!(self.current, Token::Symbol(ref sym) if sym == "}") {
1250 if matches!(self.current, Token::Eof) {
1251 return Err(ParseError {
1252 message: "Unexpected EOF in OID value".to_string(),
1253 line: self.lexer.line,
1254 column: self.lexer.column,
1255 });
1256 }
1257
1258 match &self.current {
1263 Token::Number(n) => {
1264 components.push(crate::ast::OidComponent::Number(*n));
1265 self.advance()?;
1266 }
1267 Token::Identifier(name) => {
1268 let id = name.clone();
1269 self.advance()?;
1270 if matches!(self.current, Token::Symbol(ref s) if s == "(") {
1272 self.advance()?; if let Token::Number(n) = self.current {
1274 self.advance()?;
1275 self.expect_symbol(")")?;
1276 components.push(crate::ast::OidComponent::Number(n));
1277 } else {
1278 self.expect_symbol(")")?;
1279 components.push(crate::ast::OidComponent::NamedRef(id));
1280 }
1281 } else {
1282 components.push(crate::ast::OidComponent::NamedRef(id));
1283 }
1284 }
1285 _ => {
1286 return Err(ParseError {
1287 message: format!(
1288 "Expected number or identifier in OID value, got {:?}",
1289 self.current
1290 ),
1291 line: self.lexer.line,
1292 column: self.lexer.column,
1293 });
1294 }
1295 }
1296 }
1297
1298 self.expect_symbol("}")?;
1299 Ok(crate::ast::Value::ObjectIdentifier(components))
1300 }
1301 Type::Integer(_, _) => {
1302 if let Token::Number(n) = self.current {
1304 self.advance()?;
1305 Ok(crate::ast::Value::Integer(n as i64))
1306 } else {
1307 Err(ParseError {
1308 message: format!(
1309 "Expected number for INTEGER value, got {:?}",
1310 self.current
1311 ),
1312 line: self.lexer.line,
1313 column: self.lexer.column,
1314 })
1315 }
1316 }
1317 Type::Boolean => {
1318 match &self.current {
1320 Token::Keyword(kw) if kw == "TRUE" => {
1321 self.advance()?;
1322 Ok(crate::ast::Value::Boolean(true))
1323 }
1324 Token::Keyword(kw) if kw == "FALSE" => {
1325 self.advance()?;
1326 Ok(crate::ast::Value::Boolean(false))
1327 }
1328 _ => Err(ParseError {
1329 message: format!(
1330 "Expected TRUE or FALSE for BOOLEAN value, got {:?}",
1331 self.current
1332 ),
1333 line: self.lexer.line,
1334 column: self.lexer.column,
1335 }),
1336 }
1337 }
1338 _ => Err(ParseError {
1339 message: format!("Value assignments not supported for type {:?}", ty),
1340 line: self.lexer.line,
1341 column: self.lexer.column,
1342 }),
1343 }
1344 }
1345
1346 fn parse_type(&mut self) -> Result<Type> {
1347 if let Token::Symbol(ref sym) = self.current {
1349 if sym == "[" {
1350 return self.parse_tagged_type();
1351 }
1352 }
1353
1354 if let Token::Keyword(ref kw) = self.current.clone() {
1355 match kw.as_str() {
1356 "SEQUENCE" => {
1357 self.advance()?;
1358 if matches!(self.current, Token::Keyword(ref k) if k == "OF") {
1359 self.advance()?;
1360 let inner = self.parse_type()?;
1361 let size_constraint = self.parse_size_constraint()?;
1362 return Ok(Type::SequenceOf(Box::new(inner), size_constraint));
1363 }
1364 self.expect_symbol("{")?;
1365 let fields = self.parse_sequence_fields()?;
1366 self.expect_symbol("}")?;
1367 return Ok(Type::Sequence(fields));
1368 }
1369 "SET" => {
1370 self.advance()?;
1371 if matches!(self.current, Token::Keyword(ref k) if k == "OF") {
1372 self.advance()?;
1373 let inner = self.parse_type()?;
1374 let size_constraint = self.parse_size_constraint()?;
1375 return Ok(Type::SetOf(Box::new(inner), size_constraint));
1376 }
1377 self.expect_symbol("{")?;
1378 let fields = self.parse_sequence_fields()?;
1379 self.expect_symbol("}")?;
1380 return Ok(Type::Set(fields));
1381 }
1382 "CHOICE" => {
1383 self.advance()?;
1384 self.expect_symbol("{")?;
1385 let variants = self.parse_choice_variants()?;
1386 self.expect_symbol("}")?;
1387 return Ok(Type::Choice(variants));
1388 }
1389 "INTEGER" => {
1390 self.advance()?;
1391
1392 let named_numbers = if matches!(self.current, Token::Symbol(ref s) if s == "{")
1394 {
1395 self.advance()?; let numbers = self.parse_named_numbers()?;
1397 self.expect_symbol("}")?;
1398 numbers
1399 } else {
1400 Vec::new()
1401 };
1402
1403 if matches!(self.current, Token::Symbol(ref s) if s == "(") {
1405 self.advance()?; let constraint = self.parse_subtype_constraint()?;
1407 self.expect_symbol(")")?;
1408
1409 return Ok(Type::Constrained {
1411 base_type: Box::new(Type::Integer(None, named_numbers)),
1412 constraint: Constraint {
1413 spec: ConstraintSpec::Subtype(constraint),
1414 exception: None,
1415 },
1416 });
1417 }
1418
1419 return Ok(Type::Integer(None, named_numbers));
1421 }
1422 "ENUMERATED" => {
1423 self.advance()?;
1424
1425 self.expect_symbol("{")?;
1427 let named_values = self.parse_named_numbers()?;
1428 self.expect_symbol("}")?;
1429
1430 if named_values.is_empty() {
1431 return Err(ParseError {
1432 message: "ENUMERATED must have at least one named value".to_string(),
1433 line: self.lexer.line,
1434 column: self.lexer.column,
1435 });
1436 }
1437
1438 return Ok(Type::Enumerated(named_values));
1439 }
1440 "REAL" => {
1441 self.advance()?;
1442 return Ok(Type::Real);
1443 }
1444 "BOOLEAN" => {
1445 self.advance()?;
1446 return Ok(Type::Boolean);
1447 }
1448 "OCTET" => {
1449 self.advance()?;
1450 self.expect_keyword("STRING")?;
1451
1452 if let Some(constraint) = self.parse_string_constraint()? {
1454 return Ok(Type::Constrained {
1455 base_type: Box::new(Type::OctetString(None)),
1456 constraint: Constraint {
1457 spec: ConstraintSpec::Subtype(constraint),
1458 exception: None,
1459 },
1460 });
1461 }
1462
1463 return Ok(Type::OctetString(None));
1464 }
1465 "BIT" => {
1466 self.advance()?;
1467 self.expect_keyword("STRING")?;
1468
1469 let named_bits = if matches!(self.current, Token::Symbol(ref s) if s == "{") {
1471 self.advance()?; let bits = self.parse_named_numbers()?;
1473 self.expect_symbol("}")?;
1474 bits
1475 } else {
1476 Vec::new()
1477 };
1478
1479 if let Some(size_constraint) = self.parse_string_constraint()? {
1481 if named_bits.is_empty() {
1482 return Ok(Type::Constrained {
1483 base_type: Box::new(Type::BitString(None)),
1484 constraint: Constraint {
1485 spec: ConstraintSpec::Subtype(size_constraint),
1486 exception: None,
1487 },
1488 });
1489 } else {
1490 return Ok(Type::Constrained {
1492 base_type: Box::new(Type::BitString(None)),
1493 constraint: Constraint {
1494 spec: ConstraintSpec::Subtype(SubtypeConstraint::Intersection(
1495 vec![
1496 SubtypeConstraint::NamedBitList(named_bits),
1497 size_constraint,
1498 ],
1499 )),
1500 exception: None,
1501 },
1502 });
1503 }
1504 }
1505
1506 if !named_bits.is_empty() {
1507 return Ok(Type::Constrained {
1508 base_type: Box::new(Type::BitString(None)),
1509 constraint: Constraint {
1510 spec: ConstraintSpec::Subtype(SubtypeConstraint::NamedBitList(
1511 named_bits,
1512 )),
1513 exception: None,
1514 },
1515 });
1516 }
1517
1518 return Ok(Type::BitString(None));
1519 }
1520 "OBJECT" => {
1521 self.advance()?;
1522 self.expect_keyword("IDENTIFIER")?;
1523 return Ok(Type::ObjectIdentifier);
1524 }
1525 "NULL" => {
1526 self.advance()?;
1527 return Ok(Type::Null);
1528 }
1529 "UTF8String" => return self.parse_string_type(Type::Utf8String(None)),
1530 "PrintableString" => return self.parse_string_type(Type::PrintableString(None)),
1531 "IA5String" => return self.parse_string_type(Type::IA5String(None)),
1532 "TeletexString" | "T61String" => {
1533 return self.parse_string_type(Type::TeletexString(None))
1534 }
1535 "UniversalString" => return self.parse_string_type(Type::UniversalString(None)),
1536 "BMPString" => return self.parse_string_type(Type::BmpString(None)),
1537 "GeneralString" => return self.parse_string_type(Type::GeneralString(None)),
1538 "NumericString" => return self.parse_string_type(Type::NumericString(None)),
1539 "VisibleString" => return self.parse_string_type(Type::VisibleString(None)),
1540 "UTCTime" => {
1541 self.advance()?;
1542 return Ok(Type::UtcTime);
1543 }
1544 "GeneralizedTime" => {
1545 self.advance()?;
1546 return Ok(Type::GeneralizedTime);
1547 }
1548 "ANY" => {
1549 self.advance()?;
1550 if matches!(self.current, Token::Keyword(ref kw) if kw == "DEFINED") {
1552 self.advance()?; self.expect_keyword("BY")?;
1554 let field_name = self.expect_identifier()?;
1555 return Ok(Type::AnyDefinedBy(field_name));
1556 }
1557 return Ok(Type::Any);
1558 }
1559 "CLASS" => {
1560 self.advance()?;
1561 return self.parse_class_body();
1562 }
1563 _ => {}
1564 }
1565 }
1566
1567 let type_name = if let Token::Identifier(name) = &self.current {
1570 Some(name.clone())
1571 } else if let Token::Keyword(kw) = &self.current {
1572 if is_builtin_type_keyword(kw) {
1574 Some(kw.clone())
1575 } else {
1576 None
1577 }
1578 } else {
1579 None
1580 };
1581
1582 if let Some(result) = type_name {
1583 self.advance()?;
1584
1585 if matches!(self.current, Token::Symbol(ref s) if s == "{") {
1590 self.skip_balanced_braces()?;
1591 }
1592
1593 if matches!(self.current, Token::Symbol(ref s) if s == "(") {
1595 self.advance()?; let is_string_constraint = if let Token::Keyword(ref kw) = self.current {
1600 matches!(kw.as_str(), "SIZE" | "FROM" | "PATTERN" | "CONTAINING")
1601 } else {
1602 false
1603 };
1604
1605 let constraint = if is_string_constraint {
1607 let mut constraints = Vec::new();
1609
1610 while !matches!(self.current, Token::Symbol(ref s) if s == ")") {
1611 if matches!(self.current, Token::Eof) {
1612 break;
1613 }
1614
1615 if let Some(c) = self.parse_single_string_constraint()? {
1616 constraints.push(c);
1617 } else {
1618 break;
1619 }
1620 }
1621
1622 self.expect_symbol(")")?;
1623
1624 match constraints.len() {
1625 0 => {
1626 return Err(ParseError {
1627 message: "Expected string constraint".to_string(),
1628 line: self.lexer.line,
1629 column: self.lexer.column,
1630 })
1631 }
1632 1 => constraints.into_iter().next().unwrap(),
1633 _ => SubtypeConstraint::Intersection(constraints),
1634 }
1635 } else {
1636 let c = self.parse_subtype_constraint()?;
1638 self.expect_symbol(")")?;
1639 c
1640 };
1641
1642 return Ok(Type::Constrained {
1644 base_type: Box::new(Type::TypeRef(result)),
1645 constraint: Constraint {
1646 spec: ConstraintSpec::Subtype(constraint),
1647 exception: None,
1648 },
1649 });
1650 }
1651
1652 return Ok(Type::TypeRef(result));
1653 }
1654
1655 Err(ParseError {
1656 message: format!("Expected type, got {:?}", self.current),
1657 line: self.lexer.line,
1658 column: self.lexer.column,
1659 })
1660 }
1661
1662 fn parse_tagged_type(&mut self) -> Result<Type> {
1663 self.expect_symbol("[")?;
1664
1665 let class = if matches!(self.current, Token::Keyword(ref kw) if kw == "APPLICATION") {
1667 self.advance()?;
1668 TagClass::Application
1669 } else if matches!(self.current, Token::Keyword(ref kw) if kw == "UNIVERSAL") {
1670 self.advance()?;
1671 TagClass::Universal
1672 } else if matches!(self.current, Token::Keyword(ref kw) if kw == "PRIVATE") {
1673 self.advance()?;
1674 TagClass::Private
1675 } else {
1676 TagClass::ContextSpecific
1677 };
1678
1679 let number = if let Token::Number(n) = self.current {
1680 self.advance()?;
1681 n
1682 } else {
1683 return Err(ParseError {
1684 message: "Expected tag number".to_string(),
1685 line: self.lexer.line,
1686 column: self.lexer.column,
1687 });
1688 };
1689
1690 self.expect_symbol("]")?;
1691
1692 let tagging = if matches!(self.current, Token::Keyword(ref kw) if kw == "EXPLICIT") {
1694 self.advance()?;
1695 Tagging::Explicit
1696 } else if matches!(self.current, Token::Keyword(ref kw) if kw == "IMPLICIT") {
1697 self.advance()?;
1698 Tagging::Implicit
1699 } else {
1700 self.default_tagging.clone() };
1702
1703 let inner = self.parse_type()?;
1704
1705 Ok(Type::Tagged {
1706 tag: TagInfo {
1707 class,
1708 number,
1709 tagging,
1710 },
1711 inner: Box::new(inner),
1712 })
1713 }
1714
1715 fn parse_sequence_fields(&mut self) -> Result<Vec<SequenceField>> {
1716 let mut fields = Vec::new();
1717
1718 while !matches!(self.current, Token::Symbol(ref s) if s == "}") {
1719 if matches!(self.current, Token::Eof) {
1720 break;
1721 }
1722
1723 if matches!(self.current, Token::Symbol(ref s) if s == "...") {
1725 self.advance()?;
1726 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
1727 self.advance()?;
1728 }
1729 continue;
1730 }
1731
1732 let name = self.expect_identifier()?;
1733 let ty = self.parse_type()?;
1734
1735 let optional = if matches!(self.current, Token::Keyword(ref kw) if kw == "OPTIONAL") {
1736 self.advance()?;
1737 true
1738 } else {
1739 false
1740 };
1741
1742 let default = if matches!(self.current, Token::Keyword(ref kw) if kw == "DEFAULT") {
1743 self.advance()?;
1744 let default_value = self.parse_default_value()?;
1746 Some(default_value)
1747 } else {
1748 None
1749 };
1750
1751 fields.push(SequenceField {
1752 name,
1753 ty,
1754 optional,
1755 default,
1756 });
1757
1758 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
1759 self.advance()?;
1760 }
1761 }
1762
1763 Ok(fields)
1764 }
1765
1766 fn parse_choice_variants(&mut self) -> Result<Vec<ChoiceVariant>> {
1767 let mut variants = Vec::new();
1768
1769 while !matches!(self.current, Token::Symbol(ref s) if s == "}") {
1770 if matches!(self.current, Token::Eof) {
1771 break;
1772 }
1773
1774 if matches!(self.current, Token::Symbol(ref s) if s == "...") {
1776 self.advance()?;
1777 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
1778 self.advance()?;
1779 }
1780 continue;
1781 }
1782
1783 let name = self.expect_identifier()?;
1784 let ty = self.parse_type()?;
1785
1786 variants.push(ChoiceVariant { name, ty });
1787
1788 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
1789 self.advance()?;
1790 }
1791 }
1792
1793 Ok(variants)
1794 }
1795
1796 fn parse_class_body(&mut self) -> Result<Type> {
1811 self.expect_symbol("{")?;
1812
1813 let mut fields = Vec::new();
1814
1815 while !matches!(self.current, Token::Symbol(ref s) if s == "}") {
1816 if matches!(self.current, Token::Eof) {
1817 break;
1818 }
1819
1820 if matches!(self.current, Token::Symbol(ref s) if s == "...") {
1822 self.advance()?;
1823 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
1824 self.advance()?;
1825 }
1826 continue;
1827 }
1828
1829 let field_name = if let Token::Identifier(ref id) = self.current {
1831 if id.starts_with('&') {
1832 let name = id.strip_prefix('&').unwrap_or(id).to_string();
1833 self.advance()?;
1834 name
1835 } else {
1836 self.advance()?;
1838 continue;
1839 }
1840 } else {
1841 self.advance()?;
1843 continue;
1844 };
1845
1846 let mut unique = false;
1849 let mut optional = false;
1850 let mut depth = 0usize;
1851
1852 loop {
1853 match &self.current {
1854 Token::Symbol(ref s) if s == "}" && depth == 0 => break,
1855 Token::Symbol(ref s) if s == "," && depth == 0 => break,
1856 Token::Symbol(ref s) if s == "..." && depth == 0 => break,
1857 Token::Symbol(ref s) if s == "{" => {
1858 depth += 1;
1859 self.advance()?;
1860 }
1861 Token::Symbol(ref s) if s == "}" => {
1862 depth -= 1;
1863 self.advance()?;
1864 }
1865 Token::Keyword(ref kw) if kw == "UNIQUE" && depth == 0 => {
1866 unique = true;
1867 self.advance()?;
1868 }
1869 Token::Keyword(ref kw) if kw == "OPTIONAL" && depth == 0 => {
1870 optional = true;
1871 self.advance()?;
1872 }
1873 Token::Eof => break,
1874 _ => {
1875 self.advance()?;
1876 }
1877 }
1878 }
1879
1880 fields.push(ClassField {
1881 name: field_name,
1882 unique,
1883 optional,
1884 });
1885
1886 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
1887 self.advance()?;
1888 }
1889 }
1890
1891 self.expect_symbol("}")?;
1892
1893 if matches!(self.current, Token::Keyword(ref kw) if kw == "WITH") {
1895 self.advance()?; if matches!(self.current, Token::Keyword(ref kw) if kw == "SYNTAX") {
1897 self.advance()?; self.skip_balanced_braces()?;
1900 }
1901 }
1902
1903 Ok(Type::Class(fields))
1904 }
1905
1906 fn skip_balanced_braces(&mut self) -> Result<()> {
1910 self.expect_symbol("{")?;
1911 let mut depth = 1usize;
1912 while depth > 0 {
1913 match &self.current {
1914 Token::Symbol(ref s) if s == "{" => {
1915 depth += 1;
1916 self.advance()?;
1917 }
1918 Token::Symbol(ref s) if s == "}" => {
1919 depth -= 1;
1920 self.advance()?;
1921 }
1922 Token::Eof => {
1923 return Err(ParseError {
1924 message: "Unexpected EOF inside braced block".to_string(),
1925 line: self.lexer.line,
1926 column: self.lexer.column,
1927 });
1928 }
1929 _ => {
1930 self.advance()?;
1931 }
1932 }
1933 }
1934 Ok(())
1935 }
1936
1937 fn parse_named_numbers(&mut self) -> Result<Vec<NamedNumber>> {
1939 let mut numbers = Vec::new();
1940
1941 while !matches!(self.current, Token::Symbol(ref s) if s == "}") {
1942 if matches!(self.current, Token::Eof) {
1943 break;
1944 }
1945
1946 if matches!(self.current, Token::Symbol(ref s) if s == "...") {
1948 self.advance()?;
1949 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
1950 self.advance()?;
1951 }
1952 continue;
1953 }
1954
1955 let name = self.expect_identifier()?;
1957
1958 self.expect_symbol("(")?;
1960
1961 let value = self.parse_integer_value()?.ok_or_else(|| ParseError {
1963 message: "Expected number value for named number".to_string(),
1964 line: self.lexer.line,
1965 column: self.lexer.column,
1966 })?;
1967
1968 self.expect_symbol(")")?;
1970
1971 numbers.push(NamedNumber { name, value });
1972
1973 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
1975 self.advance()?;
1976 }
1977 }
1978
1979 Ok(numbers)
1980 }
1981}
1982
1983pub fn parse(input: &str) -> Result<Module> {
1985 let mut parser = Parser::new(input)?;
1986 parser.parse_module()
1987}
1988
1989#[cfg(test)]
1990mod tests {
1991 use super::*;
1992
1993 #[test]
1994 fn test_parse_simple_sequence() {
1995 let input = r#"
1996 TestModule DEFINITIONS ::= BEGIN
1997 SimpleSeq ::= SEQUENCE {
1998 field1 INTEGER,
1999 field2 OCTET STRING
2000 }
2001 END
2002 "#;
2003
2004 let module = parse(input).unwrap();
2005 assert_eq!(module.name, "TestModule");
2006 assert_eq!(module.definitions.len(), 1);
2007
2008 let def = &module.definitions[0];
2009 assert_eq!(def.name, "SimpleSeq");
2010
2011 if let Type::Sequence(fields) = &def.ty {
2012 assert_eq!(fields.len(), 2);
2013 assert_eq!(fields[0].name, "field1");
2014 assert!(matches!(fields[0].ty, Type::Integer(_, _)));
2015 } else {
2016 panic!("Expected SEQUENCE type");
2017 }
2018 }
2019
2020 #[test]
2021 fn test_parse_choice() {
2022 let input = r#"
2023 TestModule DEFINITIONS ::= BEGIN
2024 MyChoice ::= CHOICE {
2025 option1 INTEGER,
2026 option2 BOOLEAN
2027 }
2028 END
2029 "#;
2030
2031 let module = parse(input).unwrap();
2032 let def = &module.definitions[0];
2033
2034 if let Type::Choice(variants) = &def.ty {
2035 assert_eq!(variants.len(), 2);
2036 assert_eq!(variants[0].name, "option1");
2037 } else {
2038 panic!("Expected CHOICE type");
2039 }
2040 }
2041
2042 #[test]
2043 fn test_parse_tagged_type() {
2044 let input = r#"
2045 TestModule DEFINITIONS ::= BEGIN
2046 TaggedSeq ::= SEQUENCE {
2047 field1 [0] EXPLICIT INTEGER,
2048 field2 [1] IMPLICIT OCTET STRING
2049 }
2050 END
2051 "#;
2052
2053 let module = parse(input).unwrap();
2054 let def = &module.definitions[0];
2055
2056 if let Type::Sequence(fields) = &def.ty {
2057 if let Type::Tagged { tag, .. } = &fields[0].ty {
2058 assert_eq!(tag.number, 0);
2059 assert_eq!(tag.tagging, Tagging::Explicit);
2060 } else {
2061 panic!("Expected tagged type");
2062 }
2063 } else {
2064 panic!("Expected SEQUENCE type");
2065 }
2066 }
2067
2068 #[test]
2069 fn test_implicit_tags_module_default() {
2070 let input = r#"
2073 TestModule DEFINITIONS IMPLICIT TAGS ::= BEGIN
2074 TaggedSeq ::= SEQUENCE {
2075 field1 [0] INTEGER,
2076 field2 [1] EXPLICIT OCTET STRING,
2077 field3 [2] IMPLICIT BOOLEAN
2078 }
2079 END
2080 "#;
2081
2082 let module = parse(input).unwrap();
2083 assert_eq!(module.tagging_mode, Some(crate::ast::TaggingMode::Implicit));
2084 let def = &module.definitions[0];
2085 if let Type::Sequence(fields) = &def.ty {
2086 if let Type::Tagged { tag, .. } = &fields[0].ty {
2088 assert_eq!(tag.number, 0);
2089 assert_eq!(
2090 tag.tagging,
2091 Tagging::Implicit,
2092 "bare tag should be IMPLICIT in IMPLICIT TAGS module"
2093 );
2094 } else {
2095 panic!("Expected tagged type for field1");
2096 }
2097 if let Type::Tagged { tag, .. } = &fields[1].ty {
2099 assert_eq!(tag.number, 1);
2100 assert_eq!(
2101 tag.tagging,
2102 Tagging::Explicit,
2103 "[1] EXPLICIT should stay EXPLICIT"
2104 );
2105 } else {
2106 panic!("Expected tagged type for field2");
2107 }
2108 if let Type::Tagged { tag, .. } = &fields[2].ty {
2110 assert_eq!(tag.number, 2);
2111 assert_eq!(tag.tagging, Tagging::Implicit);
2112 } else {
2113 panic!("Expected tagged type for field3");
2114 }
2115 } else {
2116 panic!("Expected SEQUENCE type");
2117 }
2118 }
2119
2120 #[test]
2121 fn test_explicit_tags_module_default() {
2122 let input = r#"
2125 TestModule DEFINITIONS EXPLICIT TAGS ::= BEGIN
2126 TaggedSeq ::= SEQUENCE {
2127 field1 [0] INTEGER
2128 }
2129 END
2130 "#;
2131
2132 let module = parse(input).unwrap();
2133 let def = &module.definitions[0];
2134 if let Type::Sequence(fields) = &def.ty {
2135 if let Type::Tagged { tag, .. } = &fields[0].ty {
2136 assert_eq!(tag.number, 0);
2137 assert_eq!(
2138 tag.tagging,
2139 Tagging::Explicit,
2140 "bare tag should be EXPLICIT in EXPLICIT TAGS module"
2141 );
2142 } else {
2143 panic!("Expected tagged type");
2144 }
2145 } else {
2146 panic!("Expected SEQUENCE type");
2147 }
2148 }
2149
2150 #[test]
2151 fn test_parse_optional_field() {
2152 let input = r#"
2153 TestModule DEFINITIONS ::= BEGIN
2154 OptSeq ::= SEQUENCE {
2155 required INTEGER,
2156 optional BOOLEAN OPTIONAL
2157 }
2158 END
2159 "#;
2160
2161 let module = parse(input).unwrap();
2162 let def = &module.definitions[0];
2163
2164 if let Type::Sequence(fields) = &def.ty {
2165 assert!(!fields[0].optional);
2166 assert!(fields[1].optional);
2167 } else {
2168 panic!("Expected SEQUENCE type");
2169 }
2170 }
2171
2172 #[test]
2173 fn test_parse_value_constraint_range() {
2174 let input = r#"
2175 TestModule DEFINITIONS ::= BEGIN
2176 Int32 ::= INTEGER (-2147483648..2147483647)
2177 END
2178 "#;
2179
2180 let module = parse(input).unwrap();
2181 let def = &module.definitions[0];
2182
2183 assert_eq!(def.name, "Int32");
2184 if let Type::Constrained {
2186 base_type,
2187 constraint,
2188 } = &def.ty
2189 {
2190 assert!(matches!(base_type.as_ref(), Type::Integer(None, _)));
2191 if let ConstraintSpec::Subtype(SubtypeConstraint::ValueRange { min, max }) =
2192 &constraint.spec
2193 {
2194 assert_eq!(*min, ConstraintValue::Integer(-2147483648));
2195 assert_eq!(*max, ConstraintValue::Integer(2147483647));
2196 } else {
2197 panic!("Expected SubtypeConstraint::ValueRange");
2198 }
2199 } else {
2200 panic!("Expected Constrained type");
2201 }
2202 }
2203
2204 #[test]
2205 fn test_parse_value_constraint_single() {
2206 let input = r#"
2207 TestModule DEFINITIONS ::= BEGIN
2208 FixedValue ::= INTEGER (42)
2209 END
2210 "#;
2211
2212 let module = parse(input).unwrap();
2213 let def = &module.definitions[0];
2214
2215 if let Type::Constrained {
2217 base_type,
2218 constraint,
2219 } = &def.ty
2220 {
2221 assert!(matches!(base_type.as_ref(), Type::Integer(None, _)));
2222 if let ConstraintSpec::Subtype(SubtypeConstraint::SingleValue(val)) = &constraint.spec {
2223 assert_eq!(*val, ConstraintValue::Integer(42));
2224 } else {
2225 panic!("Expected SubtypeConstraint::SingleValue");
2226 }
2227 } else {
2228 panic!("Expected Constrained type");
2229 }
2230 }
2231
2232 #[test]
2233 fn test_parse_size_constraint() {
2234 let input = r#"
2237TestModule DEFINITIONS ::= BEGIN
2238 ShortString ::= OCTET STRING
2239END
2240 "#;
2241
2242 let module = parse(input).unwrap();
2243 let def = &module.definitions[0];
2244
2245 assert!(matches!(def.ty, Type::OctetString(_)));
2247 }
2248
2249 #[test]
2252 fn test_parse_constraint_value_min_max() {
2253 let mut parser = Parser::new("MIN..MAX").unwrap();
2254
2255 let value1 = parser.parse_constraint_value().unwrap();
2256 assert_eq!(value1, ConstraintValue::Min);
2257
2258 parser.expect_symbol("..").unwrap();
2259
2260 let value2 = parser.parse_constraint_value().unwrap();
2261 assert_eq!(value2, ConstraintValue::Max);
2262 }
2263
2264 #[test]
2265 fn test_parse_constraint_value_integer() {
2266 let mut parser = Parser::new("42").unwrap();
2267
2268 let value = parser.parse_constraint_value().unwrap();
2269 assert_eq!(value, ConstraintValue::Integer(42));
2270 }
2271
2272 #[test]
2273 fn test_parse_constraint_value_negative() {
2274 let mut parser = Parser::new("-100").unwrap();
2275
2276 let value = parser.parse_constraint_value().unwrap();
2277 assert_eq!(value, ConstraintValue::Integer(-100));
2278 }
2279
2280 #[test]
2281 fn test_parse_constraint_value_named() {
2282 let mut parser = Parser::new("maxValue").unwrap();
2283
2284 let value = parser.parse_constraint_value().unwrap();
2285 assert_eq!(value, ConstraintValue::NamedValue("maxValue".to_string()));
2286 }
2287
2288 #[test]
2289 fn test_parse_single_value_constraint() {
2290 let mut parser = Parser::new("42").unwrap();
2291
2292 let constraint = parser.parse_single_constraint().unwrap();
2293 assert_eq!(
2294 constraint,
2295 SubtypeConstraint::SingleValue(ConstraintValue::Integer(42))
2296 );
2297 }
2298
2299 #[test]
2300 fn test_parse_value_range_constraint() {
2301 let mut parser = Parser::new("0..100").unwrap();
2302
2303 let constraint = parser.parse_single_constraint().unwrap();
2304 assert!(matches!(constraint, SubtypeConstraint::ValueRange { .. }));
2305 }
2306
2307 #[test]
2308 fn test_parse_min_max_range() {
2309 let mut parser = Parser::new("MIN..MAX").unwrap();
2310
2311 let constraint = parser.parse_single_constraint().unwrap();
2312 if let SubtypeConstraint::ValueRange { min, max } = constraint {
2313 assert_eq!(min, ConstraintValue::Min);
2314 assert_eq!(max, ConstraintValue::Max);
2315 } else {
2316 panic!("Expected ValueRange constraint");
2317 }
2318 }
2319
2320 #[test]
2321 fn test_parse_union_constraint() {
2322 let mut parser = Parser::new("1 | 2 | 3").unwrap();
2323
2324 let constraint = parser.parse_subtype_constraint().unwrap();
2325 if let SubtypeConstraint::Union(elements) = constraint {
2326 assert_eq!(elements.len(), 3);
2327 } else {
2328 panic!("Expected Union constraint");
2329 }
2330 }
2331
2332 #[test]
2333 fn test_parse_intersection_constraint() {
2334 let mut parser = Parser::new("(0..100) ^ (10 | 20 | 30)").unwrap();
2335
2336 let constraint = parser.parse_subtype_constraint().unwrap();
2337 if let SubtypeConstraint::Intersection(elements) = constraint {
2338 assert_eq!(elements.len(), 2);
2339 } else {
2340 panic!("Expected Intersection constraint");
2341 }
2342 }
2343
2344 #[test]
2345 fn test_parse_complement_constraint() {
2346 let mut parser = Parser::new("ALL EXCEPT 0").unwrap();
2347
2348 let constraint = parser.parse_single_constraint().unwrap();
2349 if let SubtypeConstraint::Complement(inner) = constraint {
2350 assert_eq!(
2351 *inner,
2352 SubtypeConstraint::SingleValue(ConstraintValue::Integer(0))
2353 );
2354 } else {
2355 panic!("Expected Complement constraint");
2356 }
2357 }
2358
2359 #[test]
2360 fn test_parse_pattern_constraint() {
2361 let input = r#"
2362TestModule DEFINITIONS ::= BEGIN
2363 EmailPattern ::= IA5String (PATTERN "[a-z]+@[a-z]+\.[a-z]+")
2364END
2365 "#;
2366
2367 let module = parse(input).unwrap();
2368 assert_eq!(module.definitions.len(), 1);
2369
2370 let def = &module.definitions[0];
2371 assert_eq!(def.name, "EmailPattern");
2372
2373 if let Type::Constrained {
2375 base_type,
2376 constraint,
2377 } = &def.ty
2378 {
2379 assert!(
2381 matches!(base_type.as_ref(), Type::IA5String(_))
2382 || matches!(base_type.as_ref(), Type::TypeRef(s) if s == "IA5String")
2383 );
2384 if let ConstraintSpec::Subtype(SubtypeConstraint::Pattern(pattern)) = &constraint.spec {
2385 assert_eq!(pattern, "[a-z]+@[a-z]+.[a-z]+");
2387 } else {
2388 panic!("Expected Pattern constraint");
2389 }
2390 } else {
2391 panic!("Expected Constrained type");
2392 }
2393 }
2394
2395 #[test]
2396 fn test_parse_permitted_alphabet() {
2397 let input = r#"
2398TestModule DEFINITIONS ::= BEGIN
2399 MyNumericString ::= IA5String (FROM ("0".."9"))
2400END
2401 "#;
2402
2403 let module = parse(input).unwrap();
2404 let def = &module.definitions[0];
2405
2406 if let Type::Constrained { constraint, .. } = &def.ty {
2407 if let ConstraintSpec::Subtype(SubtypeConstraint::PermittedAlphabet(ranges)) =
2408 &constraint.spec
2409 {
2410 assert_eq!(ranges.len(), 1);
2411 assert_eq!(ranges[0].min, '0');
2412 assert_eq!(ranges[0].max, '9');
2413 } else {
2414 panic!("Expected PermittedAlphabet constraint");
2415 }
2416 } else {
2417 panic!("Expected Constrained type");
2418 }
2419 }
2420
2421 #[test]
2422 fn test_parse_containing_constraint() {
2423 let input = r#"
2424TestModule DEFINITIONS ::= BEGIN
2425 EncodedCert ::= OCTET STRING (CONTAINING INTEGER)
2426END
2427 "#;
2428
2429 let module = parse(input).unwrap();
2430 let def = &module.definitions[0];
2431
2432 if let Type::Constrained { constraint, .. } = &def.ty {
2433 if let ConstraintSpec::Subtype(SubtypeConstraint::ContainedSubtype(inner_type)) =
2434 &constraint.spec
2435 {
2436 assert!(matches!(inner_type.as_ref(), Type::Integer(_, _)));
2437 } else {
2438 panic!("Expected ContainedSubtype constraint");
2439 }
2440 } else {
2441 panic!("Expected Constrained type");
2442 }
2443 }
2444
2445 #[test]
2446 fn test_parse_inner_type_constraint() {
2447 let input = r#"
2448TestModule DEFINITIONS ::= BEGIN
2449 PositiveList ::= SEQUENCE OF INTEGER (1..MAX)
2450END
2451 "#;
2452
2453 let module = parse(input).unwrap();
2454 let def = &module.definitions[0];
2455
2456 if let Type::SequenceOf(inner_type, _) = &def.ty {
2458 if let Type::Constrained {
2460 base_type,
2461 constraint,
2462 } = inner_type.as_ref()
2463 {
2464 assert!(matches!(base_type.as_ref(), Type::Integer(_, _)));
2465 if let ConstraintSpec::Subtype(SubtypeConstraint::ValueRange { min, max }) =
2466 &constraint.spec
2467 {
2468 assert_eq!(*min, ConstraintValue::Integer(1));
2469 assert_eq!(*max, ConstraintValue::Max);
2470 } else {
2471 panic!("Expected ValueRange constraint on inner type");
2472 }
2473 } else {
2474 panic!("Expected inner type to be Constrained");
2475 }
2476 } else {
2477 panic!("Expected SequenceOf type, got: {:?}", def.ty);
2478 }
2479 }
2480
2481 #[test]
2482 fn test_parse_complex_nested_union() {
2483 let input = r#"
2484TestModule DEFINITIONS ::= BEGIN
2485 ComplexRange ::= INTEGER (0..10 | 20..30 | 40..50)
2486END
2487 "#;
2488
2489 let module = parse(input).unwrap();
2490 let def = &module.definitions[0];
2491
2492 if let Type::Constrained { constraint, .. } = &def.ty {
2493 if let ConstraintSpec::Subtype(SubtypeConstraint::Union(elements)) = &constraint.spec {
2494 assert_eq!(elements.len(), 3);
2495 for element in elements {
2496 assert!(matches!(element, SubtypeConstraint::ValueRange { .. }));
2497 }
2498 } else {
2499 panic!("Expected Union constraint");
2500 }
2501 } else {
2502 panic!("Expected Constrained type");
2503 }
2504 }
2505
2506 #[test]
2507 fn test_parse_nested_parentheses() {
2508 let input = r#"
2509TestModule DEFINITIONS ::= BEGIN
2510 Nested ::= INTEGER ((0..10) | (20..30))
2511END
2512 "#;
2513
2514 let module = parse(input).unwrap();
2515 let def = &module.definitions[0];
2516
2517 if let Type::Constrained { constraint, .. } = &def.ty {
2518 if let ConstraintSpec::Subtype(SubtypeConstraint::Union(elements)) = &constraint.spec {
2519 assert_eq!(elements.len(), 2);
2520 } else {
2521 panic!("Expected Union constraint");
2522 }
2523 } else {
2524 panic!("Expected Constrained type");
2525 }
2526 }
2527
2528 #[test]
2529 fn test_parse_size_constraint_on_string() {
2530 let input = r#"
2531TestModule DEFINITIONS ::= BEGIN
2532 ShortString ::= IA5String (SIZE (1..64))
2533END
2534 "#;
2535
2536 let result = parse(input);
2537 if let Err(e) = &result {
2538 println!("Parse error: {}", e);
2539 }
2540 let module = result.unwrap();
2541 let def = &module.definitions[0];
2542
2543 assert_eq!(def.name, "ShortString");
2544 if let Type::Constrained {
2546 base_type,
2547 constraint,
2548 } = &def.ty
2549 {
2550 println!("base_type: {:?}", base_type);
2553 assert!(
2555 matches!(base_type.as_ref(), Type::IA5String(None))
2556 || matches!(base_type.as_ref(), Type::TypeRef(s) if s == "IA5String")
2557 );
2558 if let ConstraintSpec::Subtype(SubtypeConstraint::SizeConstraint(inner)) =
2559 &constraint.spec
2560 {
2561 if let SubtypeConstraint::ValueRange { min, max } = inner.as_ref() {
2563 assert_eq!(*min, ConstraintValue::Integer(1));
2564 assert_eq!(*max, ConstraintValue::Integer(64));
2565 } else {
2566 panic!("Expected ValueRange inside SIZE constraint");
2567 }
2568 } else {
2569 panic!("Expected SizeConstraint, got {:?}", constraint.spec);
2570 }
2571 } else {
2572 panic!("Expected Constrained type, got {:?}", def.ty);
2573 }
2574 }
2575}