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_class_alias()? {
1069 } else if self.try_skip_ioc_assignment()? {
1071 } else {
1073 definitions.push(self.parse_definition()?);
1074 }
1075 }
1076
1077 if matches!(self.current, Token::Keyword(ref kw) if kw == "END") {
1078 self.advance()?;
1079 }
1080
1081 Ok(Module {
1082 name,
1083 oid,
1084 tagging_mode,
1085 imports,
1086 exports,
1087 definitions,
1088 values,
1089 })
1090 }
1091
1092 fn parse_module_oid(&mut self) -> Result<Vec<String>> {
1095 self.expect_symbol("{")?;
1096 let mut oid_parts = Vec::new();
1097
1098 while !matches!(self.current, Token::Symbol(ref sym) if sym == "}") {
1100 match &self.current {
1101 Token::Identifier(id) => {
1102 oid_parts.push(id.clone());
1103 self.advance()?;
1104
1105 if let Token::Symbol(ref sym) = self.current {
1107 if sym == "(" {
1108 self.advance()?;
1109 if let Token::Number(n) = self.current {
1110 oid_parts.push(n.to_string());
1111 self.advance()?;
1112 }
1113 self.expect_symbol(")")?;
1114 }
1115 }
1116 }
1117 Token::Number(n) => {
1118 oid_parts.push(n.to_string());
1119 self.advance()?;
1120 }
1121 Token::Eof => {
1122 return Err(ParseError {
1123 message: "Unexpected end of input in module OID".to_string(),
1124 line: self.lexer.line,
1125 column: self.lexer.column,
1126 });
1127 }
1128 _ => {
1129 self.advance()?;
1131 }
1132 }
1133 }
1134
1135 self.expect_symbol("}")?;
1136 Ok(oid_parts)
1137 }
1138
1139 fn parse_definition(&mut self) -> Result<Definition> {
1140 let name = self.expect_identifier()?;
1141
1142 if matches!(self.current, Token::Symbol(ref s) if s == "{") {
1147 self.skip_balanced_braces()?;
1148 }
1149
1150 self.expect_symbol("::=")?;
1151 let ty = self.parse_type()?;
1152
1153 if matches!(self.current, Token::Symbol(ref s) if s == "(") {
1160 self.skip_balanced_parens()?;
1161 }
1162
1163 Ok(Definition { name, ty })
1164 }
1165
1166 fn try_parse_value_assignment(&mut self) -> Result<Option<crate::ast::ValueAssignment>> {
1169 let is_value_assignment = if let Token::Identifier(_) = &self.current {
1177 matches!(self.peek_next_token(), Token::Keyword(ref kw)
1179 if kw == "OBJECT" || kw == "INTEGER" || kw == "BOOLEAN")
1180 } else {
1181 false
1182 };
1183
1184 if !is_value_assignment {
1185 return Ok(None);
1186 }
1187
1188 let name = self.expect_identifier()?;
1190 let ty = self.parse_type()?;
1191 self.expect_symbol("::=")?;
1192 let value = self.parse_value(&ty)?;
1193
1194 Ok(Some(crate::ast::ValueAssignment { name, ty, value }))
1195 }
1196
1197 fn try_skip_class_alias(&mut self) -> Result<bool> {
1204 let is_ident = matches!(self.current, Token::Identifier(_));
1207 if !is_ident {
1208 return Ok(false);
1209 }
1210
1211 let saved_lexer = self.lexer.clone();
1213 let saved_current = self.current.clone();
1214
1215 self.advance()?; if !matches!(self.current, Token::Symbol(ref s) if s == "::=") {
1219 self.lexer = saved_lexer;
1220 self.current = saved_current;
1221 return Ok(false);
1222 }
1223 self.advance()?; let is_class_keyword = matches!(
1227 self.current,
1228 Token::Keyword(ref kw) if kw == "TYPE-IDENTIFIER" || kw == "ABSTRACT-SYNTAX"
1229 );
1230
1231 if !is_class_keyword {
1232 self.lexer = saved_lexer;
1234 self.current = saved_current;
1235 return Ok(false);
1236 }
1237
1238 self.advance()?;
1240 Ok(true)
1241 }
1242
1243 fn try_skip_ioc_assignment(&mut self) -> Result<bool> {
1256 let is_ioc = if let Token::Identifier(_) = &self.current {
1259 matches!(self.peek_next_token(), Token::Identifier(_))
1260 } else {
1261 false
1262 };
1263
1264 if !is_ioc {
1265 return Ok(false);
1266 }
1267
1268 let saved_lexer = self.lexer.clone();
1271 let saved_current = self.current.clone();
1272
1273 self.advance()?; self.advance()?; if !matches!(self.current, Token::Symbol(ref s) if s == "::=") {
1278 self.lexer = saved_lexer;
1280 self.current = saved_current;
1281 return Ok(false);
1282 }
1283 self.advance()?; if matches!(self.current, Token::Symbol(ref s) if s == "{") {
1286 self.skip_balanced_braces()?;
1287 } else {
1288 self.advance()?;
1290 }
1291
1292 Ok(true)
1293 }
1294
1295 fn peek_next_token(&mut self) -> Token {
1297 let saved_lexer = self.lexer.clone();
1299 let saved_current = self.current.clone();
1300
1301 let _ = self.advance();
1303 let next = self.current.clone();
1304
1305 self.lexer = saved_lexer;
1307 self.current = saved_current;
1308
1309 next
1310 }
1311
1312 fn parse_value(&mut self, ty: &Type) -> Result<crate::ast::Value> {
1314 match ty {
1315 Type::ObjectIdentifier => {
1316 self.expect_symbol("{")?;
1318 let mut components = Vec::new();
1319
1320 while !matches!(self.current, Token::Symbol(ref sym) if sym == "}") {
1321 if matches!(self.current, Token::Eof) {
1322 return Err(ParseError {
1323 message: "Unexpected EOF in OID value".to_string(),
1324 line: self.lexer.line,
1325 column: self.lexer.column,
1326 });
1327 }
1328
1329 match &self.current {
1334 Token::Number(n) => {
1335 components.push(crate::ast::OidComponent::Number(*n));
1336 self.advance()?;
1337 }
1338 Token::Identifier(name) => {
1339 let id = name.clone();
1340 self.advance()?;
1341 if matches!(self.current, Token::Symbol(ref s) if s == "(") {
1343 self.advance()?; if let Token::Number(n) = self.current {
1345 self.advance()?;
1346 self.expect_symbol(")")?;
1347 components.push(crate::ast::OidComponent::Number(n));
1348 } else {
1349 self.expect_symbol(")")?;
1350 components.push(crate::ast::OidComponent::NamedRef(id));
1351 }
1352 } else {
1353 components.push(crate::ast::OidComponent::NamedRef(id));
1354 }
1355 }
1356 _ => {
1357 return Err(ParseError {
1358 message: format!(
1359 "Expected number or identifier in OID value, got {:?}",
1360 self.current
1361 ),
1362 line: self.lexer.line,
1363 column: self.lexer.column,
1364 });
1365 }
1366 }
1367 }
1368
1369 self.expect_symbol("}")?;
1370 Ok(crate::ast::Value::ObjectIdentifier(components))
1371 }
1372 Type::Integer(_, _) => {
1373 if let Token::Number(n) = self.current {
1375 self.advance()?;
1376 Ok(crate::ast::Value::Integer(n as i64))
1377 } else {
1378 Err(ParseError {
1379 message: format!(
1380 "Expected number for INTEGER value, got {:?}",
1381 self.current
1382 ),
1383 line: self.lexer.line,
1384 column: self.lexer.column,
1385 })
1386 }
1387 }
1388 Type::Boolean => {
1389 match &self.current {
1391 Token::Keyword(kw) if kw == "TRUE" => {
1392 self.advance()?;
1393 Ok(crate::ast::Value::Boolean(true))
1394 }
1395 Token::Keyword(kw) if kw == "FALSE" => {
1396 self.advance()?;
1397 Ok(crate::ast::Value::Boolean(false))
1398 }
1399 _ => Err(ParseError {
1400 message: format!(
1401 "Expected TRUE or FALSE for BOOLEAN value, got {:?}",
1402 self.current
1403 ),
1404 line: self.lexer.line,
1405 column: self.lexer.column,
1406 }),
1407 }
1408 }
1409 _ => Err(ParseError {
1410 message: format!("Value assignments not supported for type {:?}", ty),
1411 line: self.lexer.line,
1412 column: self.lexer.column,
1413 }),
1414 }
1415 }
1416
1417 fn parse_type(&mut self) -> Result<Type> {
1418 if let Token::Symbol(ref sym) = self.current {
1420 if sym == "[" {
1421 return self.parse_tagged_type();
1422 }
1423 }
1424
1425 if let Token::Keyword(ref kw) = self.current.clone() {
1426 match kw.as_str() {
1427 "SEQUENCE" => {
1428 self.advance()?;
1429 if matches!(self.current, Token::Keyword(ref k) if k == "SIZE") {
1431 self.advance()?; if matches!(self.current, Token::Symbol(ref s) if s == "(") {
1435 self.skip_balanced_parens()?;
1436 }
1437 }
1438 if matches!(self.current, Token::Keyword(ref k) if k == "OF") {
1439 self.advance()?;
1440 let inner = self.parse_type()?;
1441 let size_constraint = self.parse_size_constraint()?;
1442 return Ok(Type::SequenceOf(Box::new(inner), size_constraint));
1443 }
1444 self.expect_symbol("{")?;
1445 let fields = self.parse_sequence_fields()?;
1446 self.expect_symbol("}")?;
1447 return Ok(Type::Sequence(fields));
1448 }
1449 "SET" => {
1450 self.advance()?;
1451 if matches!(self.current, Token::Keyword(ref k) if k == "SIZE") {
1453 self.advance()?; if matches!(self.current, Token::Symbol(ref s) if s == "(") {
1457 self.skip_balanced_parens()?;
1458 }
1459 }
1460 if matches!(self.current, Token::Keyword(ref k) if k == "OF") {
1461 self.advance()?;
1462 let inner = self.parse_type()?;
1463 let size_constraint = self.parse_size_constraint()?;
1464 return Ok(Type::SetOf(Box::new(inner), size_constraint));
1465 }
1466 self.expect_symbol("{")?;
1467 let fields = self.parse_sequence_fields()?;
1468 self.expect_symbol("}")?;
1469 return Ok(Type::Set(fields));
1470 }
1471 "CHOICE" => {
1472 self.advance()?;
1473 self.expect_symbol("{")?;
1474 let variants = self.parse_choice_variants()?;
1475 self.expect_symbol("}")?;
1476 return Ok(Type::Choice(variants));
1477 }
1478 "INTEGER" => {
1479 self.advance()?;
1480
1481 let named_numbers = if matches!(self.current, Token::Symbol(ref s) if s == "{")
1483 {
1484 self.advance()?; let numbers = self.parse_named_numbers()?;
1486 self.expect_symbol("}")?;
1487 numbers
1488 } else {
1489 Vec::new()
1490 };
1491
1492 if matches!(self.current, Token::Symbol(ref s) if s == "(") {
1494 self.advance()?; let constraint = self.parse_subtype_constraint()?;
1496 self.expect_symbol(")")?;
1497
1498 return Ok(Type::Constrained {
1500 base_type: Box::new(Type::Integer(None, named_numbers)),
1501 constraint: Constraint {
1502 spec: ConstraintSpec::Subtype(constraint),
1503 exception: None,
1504 },
1505 });
1506 }
1507
1508 return Ok(Type::Integer(None, named_numbers));
1510 }
1511 "ENUMERATED" => {
1512 self.advance()?;
1513
1514 self.expect_symbol("{")?;
1516 let named_values = self.parse_named_numbers()?;
1517 self.expect_symbol("}")?;
1518
1519 if named_values.is_empty() {
1520 return Err(ParseError {
1521 message: "ENUMERATED must have at least one named value".to_string(),
1522 line: self.lexer.line,
1523 column: self.lexer.column,
1524 });
1525 }
1526
1527 return Ok(Type::Enumerated(named_values));
1528 }
1529 "REAL" => {
1530 self.advance()?;
1531 return Ok(Type::Real);
1532 }
1533 "BOOLEAN" => {
1534 self.advance()?;
1535 return Ok(Type::Boolean);
1536 }
1537 "OCTET" => {
1538 self.advance()?;
1539 self.expect_keyword("STRING")?;
1540
1541 if let Some(constraint) = self.parse_string_constraint()? {
1543 return Ok(Type::Constrained {
1544 base_type: Box::new(Type::OctetString(None)),
1545 constraint: Constraint {
1546 spec: ConstraintSpec::Subtype(constraint),
1547 exception: None,
1548 },
1549 });
1550 }
1551
1552 return Ok(Type::OctetString(None));
1553 }
1554 "BIT" => {
1555 self.advance()?;
1556 self.expect_keyword("STRING")?;
1557
1558 let named_bits = if matches!(self.current, Token::Symbol(ref s) if s == "{") {
1560 self.advance()?; let bits = self.parse_named_numbers()?;
1562 self.expect_symbol("}")?;
1563 bits
1564 } else {
1565 Vec::new()
1566 };
1567
1568 if let Some(size_constraint) = self.parse_string_constraint()? {
1570 if named_bits.is_empty() {
1571 return Ok(Type::Constrained {
1572 base_type: Box::new(Type::BitString(None)),
1573 constraint: Constraint {
1574 spec: ConstraintSpec::Subtype(size_constraint),
1575 exception: None,
1576 },
1577 });
1578 } else {
1579 return Ok(Type::Constrained {
1581 base_type: Box::new(Type::BitString(None)),
1582 constraint: Constraint {
1583 spec: ConstraintSpec::Subtype(SubtypeConstraint::Intersection(
1584 vec![
1585 SubtypeConstraint::NamedBitList(named_bits),
1586 size_constraint,
1587 ],
1588 )),
1589 exception: None,
1590 },
1591 });
1592 }
1593 }
1594
1595 if !named_bits.is_empty() {
1596 return Ok(Type::Constrained {
1597 base_type: Box::new(Type::BitString(None)),
1598 constraint: Constraint {
1599 spec: ConstraintSpec::Subtype(SubtypeConstraint::NamedBitList(
1600 named_bits,
1601 )),
1602 exception: None,
1603 },
1604 });
1605 }
1606
1607 return Ok(Type::BitString(None));
1608 }
1609 "OBJECT" => {
1610 self.advance()?;
1611 self.expect_keyword("IDENTIFIER")?;
1612 return Ok(Type::ObjectIdentifier);
1613 }
1614 "NULL" => {
1615 self.advance()?;
1616 return Ok(Type::Null);
1617 }
1618 "UTF8String" => return self.parse_string_type(Type::Utf8String(None)),
1619 "PrintableString" => return self.parse_string_type(Type::PrintableString(None)),
1620 "IA5String" => return self.parse_string_type(Type::IA5String(None)),
1621 "TeletexString" | "T61String" => {
1622 return self.parse_string_type(Type::TeletexString(None))
1623 }
1624 "UniversalString" => return self.parse_string_type(Type::UniversalString(None)),
1625 "BMPString" => return self.parse_string_type(Type::BmpString(None)),
1626 "GeneralString" => return self.parse_string_type(Type::GeneralString(None)),
1627 "NumericString" => return self.parse_string_type(Type::NumericString(None)),
1628 "VisibleString" => return self.parse_string_type(Type::VisibleString(None)),
1629 "UTCTime" => {
1630 self.advance()?;
1631 return Ok(Type::UtcTime);
1632 }
1633 "GeneralizedTime" => {
1634 self.advance()?;
1635 return Ok(Type::GeneralizedTime);
1636 }
1637 "ANY" => {
1638 self.advance()?;
1639 if matches!(self.current, Token::Keyword(ref kw) if kw == "DEFINED") {
1641 self.advance()?; self.expect_keyword("BY")?;
1643 let field_name = self.expect_identifier()?;
1644 return Ok(Type::AnyDefinedBy(field_name));
1645 }
1646 return Ok(Type::Any);
1647 }
1648 "CLASS" => {
1649 self.advance()?;
1650 return self.parse_class_body();
1651 }
1652 "TYPE-IDENTIFIER" | "ABSTRACT-SYNTAX" => {
1657 self.advance()?;
1658 return Ok(Type::Any);
1659 }
1660 _ => {}
1661 }
1662 }
1663
1664 let type_name = if let Token::Identifier(name) = &self.current {
1667 Some(name.clone())
1668 } else if let Token::Keyword(kw) = &self.current {
1669 if is_builtin_type_keyword(kw) {
1671 Some(kw.clone())
1672 } else {
1673 None
1674 }
1675 } else {
1676 None
1677 };
1678
1679 if let Some(result) = type_name {
1680 self.advance()?;
1681
1682 if matches!(self.current, Token::Symbol(ref s) if s == "{") {
1687 self.skip_balanced_braces()?;
1688 }
1689
1690 if result == "INSTANCE" && matches!(self.current, Token::Keyword(ref k) if k == "OF") {
1694 self.advance()?; self.advance()?;
1698 if matches!(self.current, Token::Symbol(ref s) if s == "{") {
1700 self.skip_balanced_braces()?;
1701 }
1702 return Ok(Type::Any);
1703 }
1704
1705 if matches!(self.current, Token::Symbol(ref s) if s == ".") {
1714 self.advance()?; let field_name = if let Token::Identifier(ref name) = self.current {
1718 let n = name.clone();
1719 self.advance()?;
1720 n
1721 } else {
1722 self.advance()?;
1723 String::new()
1724 };
1725 loop {
1727 if matches!(self.current, Token::Symbol(ref s) if s == "{") {
1728 self.skip_balanced_braces()?;
1729 } else if matches!(self.current, Token::Symbol(ref s) if s == "(") {
1730 self.skip_balanced_parens()?;
1731 } else {
1732 break;
1733 }
1734 }
1735 if field_name == "&id" {
1737 return Ok(Type::ObjectIdentifier);
1738 }
1739 return Ok(Type::Any);
1740 }
1741
1742 if matches!(self.current, Token::Symbol(ref s) if s == "(") {
1744 self.advance()?; let is_string_constraint = if let Token::Keyword(ref kw) = self.current {
1749 matches!(kw.as_str(), "SIZE" | "FROM" | "PATTERN" | "CONTAINING")
1750 } else {
1751 false
1752 };
1753
1754 let constraint = if is_string_constraint {
1756 let mut constraints = Vec::new();
1758
1759 while !matches!(self.current, Token::Symbol(ref s) if s == ")") {
1760 if matches!(self.current, Token::Eof) {
1761 break;
1762 }
1763
1764 if let Some(c) = self.parse_single_string_constraint()? {
1765 constraints.push(c);
1766 } else {
1767 break;
1768 }
1769 }
1770
1771 self.expect_symbol(")")?;
1772
1773 match constraints.len() {
1774 0 => {
1775 return Err(ParseError {
1776 message: "Expected string constraint".to_string(),
1777 line: self.lexer.line,
1778 column: self.lexer.column,
1779 })
1780 }
1781 1 => constraints.into_iter().next().unwrap(),
1782 _ => SubtypeConstraint::Intersection(constraints),
1783 }
1784 } else {
1785 let c = self.parse_subtype_constraint()?;
1787 self.expect_symbol(")")?;
1788 c
1789 };
1790
1791 return Ok(Type::Constrained {
1793 base_type: Box::new(Type::TypeRef(result)),
1794 constraint: Constraint {
1795 spec: ConstraintSpec::Subtype(constraint),
1796 exception: None,
1797 },
1798 });
1799 }
1800
1801 return Ok(Type::TypeRef(result));
1802 }
1803
1804 Err(ParseError {
1805 message: format!("Expected type, got {:?}", self.current),
1806 line: self.lexer.line,
1807 column: self.lexer.column,
1808 })
1809 }
1810
1811 fn parse_tagged_type(&mut self) -> Result<Type> {
1812 self.expect_symbol("[")?;
1813
1814 let class = if matches!(self.current, Token::Keyword(ref kw) if kw == "APPLICATION") {
1816 self.advance()?;
1817 TagClass::Application
1818 } else if matches!(self.current, Token::Keyword(ref kw) if kw == "UNIVERSAL") {
1819 self.advance()?;
1820 TagClass::Universal
1821 } else if matches!(self.current, Token::Keyword(ref kw) if kw == "PRIVATE") {
1822 self.advance()?;
1823 TagClass::Private
1824 } else {
1825 TagClass::ContextSpecific
1826 };
1827
1828 let number = if let Token::Number(n) = self.current {
1829 self.advance()?;
1830 n
1831 } else {
1832 return Err(ParseError {
1833 message: "Expected tag number".to_string(),
1834 line: self.lexer.line,
1835 column: self.lexer.column,
1836 });
1837 };
1838
1839 self.expect_symbol("]")?;
1840
1841 let tagging = if matches!(self.current, Token::Keyword(ref kw) if kw == "EXPLICIT") {
1843 self.advance()?;
1844 Tagging::Explicit
1845 } else if matches!(self.current, Token::Keyword(ref kw) if kw == "IMPLICIT") {
1846 self.advance()?;
1847 Tagging::Implicit
1848 } else {
1849 self.default_tagging.clone() };
1851
1852 let inner = self.parse_type()?;
1853
1854 Ok(Type::Tagged {
1855 tag: TagInfo {
1856 class,
1857 number,
1858 tagging,
1859 },
1860 inner: Box::new(inner),
1861 })
1862 }
1863
1864 fn parse_sequence_fields(&mut self) -> Result<Vec<SequenceField>> {
1865 let mut fields = Vec::new();
1866
1867 while !matches!(self.current, Token::Symbol(ref s) if s == "}") {
1868 if matches!(self.current, Token::Eof) {
1869 break;
1870 }
1871
1872 if matches!(self.current, Token::Symbol(ref s) if s == "...") {
1874 self.advance()?;
1875 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
1876 self.advance()?;
1877 }
1878 continue;
1879 }
1880
1881 if matches!(self.current, Token::Symbol(ref s) if s == "[") {
1885 let saved_lexer = self.lexer.clone();
1887 let saved_current = self.current.clone();
1888 self.advance()?; if matches!(self.current, Token::Symbol(ref s) if s == "[") {
1890 self.advance()?; if let Token::Number(_) = self.current {
1893 self.advance()?; }
1895 if matches!(self.current, Token::Symbol(ref s) if s == ":") {
1896 self.advance()?; }
1898 while !matches!(self.current, Token::Symbol(ref s) if s == "]" || s == "}") {
1900 if matches!(self.current, Token::Eof) {
1901 break;
1902 }
1903 if matches!(self.current, Token::Symbol(ref s) if s == "...") {
1905 self.advance()?;
1906 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
1907 self.advance()?;
1908 }
1909 continue;
1910 }
1911 let fname = self.expect_identifier()?;
1912 let fty = self.parse_type()?;
1913 let foptional = if matches!(self.current, Token::Keyword(ref kw) if kw == "OPTIONAL")
1914 {
1915 self.advance()?;
1916 true
1917 } else {
1918 false
1919 };
1920 let fdefault = if matches!(self.current, Token::Keyword(ref kw) if kw == "DEFAULT")
1921 {
1922 self.advance()?;
1923 let dv = self.parse_default_value()?;
1924 Some(dv)
1925 } else {
1926 None
1927 };
1928 fields.push(SequenceField {
1929 name: fname,
1930 ty: fty,
1931 optional: foptional,
1932 default: fdefault,
1933 });
1934 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
1935 self.advance()?;
1936 }
1937 }
1938 if matches!(self.current, Token::Symbol(ref s) if s == "]") {
1940 self.advance()?; }
1942 if matches!(self.current, Token::Symbol(ref s) if s == "]") {
1943 self.advance()?; }
1945 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
1946 self.advance()?;
1947 }
1948 continue;
1949 } else {
1950 self.lexer = saved_lexer;
1952 self.current = saved_current;
1953 }
1954 }
1955
1956 let name = self.expect_identifier()?;
1957 let ty = self.parse_type()?;
1958
1959 let optional = if matches!(self.current, Token::Keyword(ref kw) if kw == "OPTIONAL") {
1960 self.advance()?;
1961 true
1962 } else {
1963 false
1964 };
1965
1966 let default = if matches!(self.current, Token::Keyword(ref kw) if kw == "DEFAULT") {
1967 self.advance()?;
1968 let default_value = self.parse_default_value()?;
1970 Some(default_value)
1971 } else {
1972 None
1973 };
1974
1975 fields.push(SequenceField {
1976 name,
1977 ty,
1978 optional,
1979 default,
1980 });
1981
1982 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
1983 self.advance()?;
1984 }
1985 }
1986
1987 Ok(fields)
1988 }
1989
1990 fn parse_choice_variants(&mut self) -> Result<Vec<ChoiceVariant>> {
1991 let mut variants = Vec::new();
1992
1993 while !matches!(self.current, Token::Symbol(ref s) if s == "}") {
1994 if matches!(self.current, Token::Eof) {
1995 break;
1996 }
1997
1998 if matches!(self.current, Token::Symbol(ref s) if s == "...") {
2000 self.advance()?;
2001 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
2002 self.advance()?;
2003 }
2004 continue;
2005 }
2006
2007 let name = self.expect_identifier()?;
2008 let ty = self.parse_type()?;
2009
2010 variants.push(ChoiceVariant { name, ty });
2011
2012 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
2013 self.advance()?;
2014 }
2015 }
2016
2017 Ok(variants)
2018 }
2019
2020 fn parse_class_body(&mut self) -> Result<Type> {
2035 self.expect_symbol("{")?;
2036
2037 let mut fields = Vec::new();
2038
2039 while !matches!(self.current, Token::Symbol(ref s) if s == "}") {
2040 if matches!(self.current, Token::Eof) {
2041 break;
2042 }
2043
2044 if matches!(self.current, Token::Symbol(ref s) if s == "...") {
2046 self.advance()?;
2047 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
2048 self.advance()?;
2049 }
2050 continue;
2051 }
2052
2053 let field_name = if let Token::Identifier(ref id) = self.current {
2055 if id.starts_with('&') {
2056 let name = id.strip_prefix('&').unwrap_or(id).to_string();
2057 self.advance()?;
2058 name
2059 } else {
2060 self.advance()?;
2062 continue;
2063 }
2064 } else {
2065 self.advance()?;
2067 continue;
2068 };
2069
2070 let mut unique = false;
2073 let mut optional = false;
2074 let mut depth = 0usize;
2075
2076 loop {
2077 match &self.current {
2078 Token::Symbol(ref s) if s == "}" && depth == 0 => break,
2079 Token::Symbol(ref s) if s == "," && depth == 0 => break,
2080 Token::Symbol(ref s) if s == "..." && depth == 0 => break,
2081 Token::Symbol(ref s) if s == "{" => {
2082 depth += 1;
2083 self.advance()?;
2084 }
2085 Token::Symbol(ref s) if s == "}" => {
2086 depth -= 1;
2087 self.advance()?;
2088 }
2089 Token::Keyword(ref kw) if kw == "UNIQUE" && depth == 0 => {
2090 unique = true;
2091 self.advance()?;
2092 }
2093 Token::Keyword(ref kw) if kw == "OPTIONAL" && depth == 0 => {
2094 optional = true;
2095 self.advance()?;
2096 }
2097 Token::Eof => break,
2098 _ => {
2099 self.advance()?;
2100 }
2101 }
2102 }
2103
2104 fields.push(ClassField {
2105 name: field_name,
2106 unique,
2107 optional,
2108 });
2109
2110 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
2111 self.advance()?;
2112 }
2113 }
2114
2115 self.expect_symbol("}")?;
2116
2117 if matches!(self.current, Token::Keyword(ref kw) if kw == "WITH") {
2119 self.advance()?; if matches!(self.current, Token::Keyword(ref kw) if kw == "SYNTAX") {
2121 self.advance()?; self.skip_balanced_braces()?;
2124 }
2125 }
2126
2127 Ok(Type::Class(fields))
2128 }
2129
2130 fn skip_balanced_braces(&mut self) -> Result<()> {
2134 self.expect_symbol("{")?;
2135 let mut depth = 1usize;
2136 while depth > 0 {
2137 match &self.current {
2138 Token::Symbol(ref s) if s == "{" => {
2139 depth += 1;
2140 self.advance()?;
2141 }
2142 Token::Symbol(ref s) if s == "}" => {
2143 depth -= 1;
2144 self.advance()?;
2145 }
2146 Token::Eof => {
2147 return Err(ParseError {
2148 message: "Unexpected EOF inside braced block".to_string(),
2149 line: self.lexer.line,
2150 column: self.lexer.column,
2151 });
2152 }
2153 _ => {
2154 self.advance()?;
2155 }
2156 }
2157 }
2158 Ok(())
2159 }
2160
2161 fn skip_balanced_parens(&mut self) -> Result<()> {
2167 self.expect_symbol("(")?;
2168 let mut depth = 1usize;
2169 while depth > 0 {
2170 match &self.current {
2171 Token::Symbol(ref s) if s == "(" => {
2172 depth += 1;
2173 self.advance()?;
2174 }
2175 Token::Symbol(ref s) if s == ")" => {
2176 depth -= 1;
2177 self.advance()?;
2178 }
2179 Token::Eof => {
2180 return Err(ParseError {
2181 message: "Unexpected EOF inside parenthesized block".to_string(),
2182 line: self.lexer.line,
2183 column: self.lexer.column,
2184 });
2185 }
2186 _ => {
2187 self.advance()?;
2188 }
2189 }
2190 }
2191 Ok(())
2192 }
2193
2194 fn parse_named_numbers(&mut self) -> Result<Vec<NamedNumber>> {
2196 let mut numbers = Vec::new();
2197
2198 while !matches!(self.current, Token::Symbol(ref s) if s == "}") {
2199 if matches!(self.current, Token::Eof) {
2200 break;
2201 }
2202
2203 if matches!(self.current, Token::Symbol(ref s) if s == "...") {
2205 self.advance()?;
2206 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
2207 self.advance()?;
2208 }
2209 continue;
2210 }
2211
2212 let name = self.expect_identifier()?;
2214
2215 let value = if matches!(self.current, Token::Symbol(ref s) if s == "(") {
2218 self.advance()?; let v = self.parse_integer_value()?.ok_or_else(|| ParseError {
2220 message: "Expected number value for named number".to_string(),
2221 line: self.lexer.line,
2222 column: self.lexer.column,
2223 })?;
2224 self.expect_symbol(")")?;
2225 v
2226 } else {
2227 numbers
2229 .last()
2230 .map(|n: &NamedNumber| n.value + 1)
2231 .unwrap_or(0)
2232 };
2233
2234 numbers.push(NamedNumber { name, value });
2235
2236 if matches!(self.current, Token::Symbol(ref s) if s == ",") {
2238 self.advance()?;
2239 }
2240 }
2241
2242 Ok(numbers)
2243 }
2244}
2245
2246pub fn parse(input: &str) -> Result<Module> {
2248 let mut parser = Parser::new(input)?;
2249 parser.parse_module()
2250}
2251
2252#[cfg(test)]
2253mod tests {
2254 use super::*;
2255
2256 #[test]
2257 fn test_parse_simple_sequence() {
2258 let input = r#"
2259 TestModule DEFINITIONS ::= BEGIN
2260 SimpleSeq ::= SEQUENCE {
2261 field1 INTEGER,
2262 field2 OCTET STRING
2263 }
2264 END
2265 "#;
2266
2267 let module = parse(input).unwrap();
2268 assert_eq!(module.name, "TestModule");
2269 assert_eq!(module.definitions.len(), 1);
2270
2271 let def = &module.definitions[0];
2272 assert_eq!(def.name, "SimpleSeq");
2273
2274 if let Type::Sequence(fields) = &def.ty {
2275 assert_eq!(fields.len(), 2);
2276 assert_eq!(fields[0].name, "field1");
2277 assert!(matches!(fields[0].ty, Type::Integer(_, _)));
2278 } else {
2279 panic!("Expected SEQUENCE type");
2280 }
2281 }
2282
2283 #[test]
2284 fn test_parse_choice() {
2285 let input = r#"
2286 TestModule DEFINITIONS ::= BEGIN
2287 MyChoice ::= CHOICE {
2288 option1 INTEGER,
2289 option2 BOOLEAN
2290 }
2291 END
2292 "#;
2293
2294 let module = parse(input).unwrap();
2295 let def = &module.definitions[0];
2296
2297 if let Type::Choice(variants) = &def.ty {
2298 assert_eq!(variants.len(), 2);
2299 assert_eq!(variants[0].name, "option1");
2300 } else {
2301 panic!("Expected CHOICE type");
2302 }
2303 }
2304
2305 #[test]
2306 fn test_parse_tagged_type() {
2307 let input = r#"
2308 TestModule DEFINITIONS ::= BEGIN
2309 TaggedSeq ::= SEQUENCE {
2310 field1 [0] EXPLICIT INTEGER,
2311 field2 [1] IMPLICIT OCTET STRING
2312 }
2313 END
2314 "#;
2315
2316 let module = parse(input).unwrap();
2317 let def = &module.definitions[0];
2318
2319 if let Type::Sequence(fields) = &def.ty {
2320 if let Type::Tagged { tag, .. } = &fields[0].ty {
2321 assert_eq!(tag.number, 0);
2322 assert_eq!(tag.tagging, Tagging::Explicit);
2323 } else {
2324 panic!("Expected tagged type");
2325 }
2326 } else {
2327 panic!("Expected SEQUENCE type");
2328 }
2329 }
2330
2331 #[test]
2332 fn test_implicit_tags_module_default() {
2333 let input = r#"
2336 TestModule DEFINITIONS IMPLICIT TAGS ::= BEGIN
2337 TaggedSeq ::= SEQUENCE {
2338 field1 [0] INTEGER,
2339 field2 [1] EXPLICIT OCTET STRING,
2340 field3 [2] IMPLICIT BOOLEAN
2341 }
2342 END
2343 "#;
2344
2345 let module = parse(input).unwrap();
2346 assert_eq!(module.tagging_mode, Some(crate::ast::TaggingMode::Implicit));
2347 let def = &module.definitions[0];
2348 if let Type::Sequence(fields) = &def.ty {
2349 if let Type::Tagged { tag, .. } = &fields[0].ty {
2351 assert_eq!(tag.number, 0);
2352 assert_eq!(
2353 tag.tagging,
2354 Tagging::Implicit,
2355 "bare tag should be IMPLICIT in IMPLICIT TAGS module"
2356 );
2357 } else {
2358 panic!("Expected tagged type for field1");
2359 }
2360 if let Type::Tagged { tag, .. } = &fields[1].ty {
2362 assert_eq!(tag.number, 1);
2363 assert_eq!(
2364 tag.tagging,
2365 Tagging::Explicit,
2366 "[1] EXPLICIT should stay EXPLICIT"
2367 );
2368 } else {
2369 panic!("Expected tagged type for field2");
2370 }
2371 if let Type::Tagged { tag, .. } = &fields[2].ty {
2373 assert_eq!(tag.number, 2);
2374 assert_eq!(tag.tagging, Tagging::Implicit);
2375 } else {
2376 panic!("Expected tagged type for field3");
2377 }
2378 } else {
2379 panic!("Expected SEQUENCE type");
2380 }
2381 }
2382
2383 #[test]
2384 fn test_explicit_tags_module_default() {
2385 let input = r#"
2388 TestModule DEFINITIONS EXPLICIT TAGS ::= BEGIN
2389 TaggedSeq ::= SEQUENCE {
2390 field1 [0] INTEGER
2391 }
2392 END
2393 "#;
2394
2395 let module = parse(input).unwrap();
2396 let def = &module.definitions[0];
2397 if let Type::Sequence(fields) = &def.ty {
2398 if let Type::Tagged { tag, .. } = &fields[0].ty {
2399 assert_eq!(tag.number, 0);
2400 assert_eq!(
2401 tag.tagging,
2402 Tagging::Explicit,
2403 "bare tag should be EXPLICIT in EXPLICIT TAGS module"
2404 );
2405 } else {
2406 panic!("Expected tagged type");
2407 }
2408 } else {
2409 panic!("Expected SEQUENCE type");
2410 }
2411 }
2412
2413 #[test]
2414 fn test_parse_optional_field() {
2415 let input = r#"
2416 TestModule DEFINITIONS ::= BEGIN
2417 OptSeq ::= SEQUENCE {
2418 required INTEGER,
2419 optional BOOLEAN OPTIONAL
2420 }
2421 END
2422 "#;
2423
2424 let module = parse(input).unwrap();
2425 let def = &module.definitions[0];
2426
2427 if let Type::Sequence(fields) = &def.ty {
2428 assert!(!fields[0].optional);
2429 assert!(fields[1].optional);
2430 } else {
2431 panic!("Expected SEQUENCE type");
2432 }
2433 }
2434
2435 #[test]
2436 fn test_parse_value_constraint_range() {
2437 let input = r#"
2438 TestModule DEFINITIONS ::= BEGIN
2439 Int32 ::= INTEGER (-2147483648..2147483647)
2440 END
2441 "#;
2442
2443 let module = parse(input).unwrap();
2444 let def = &module.definitions[0];
2445
2446 assert_eq!(def.name, "Int32");
2447 if let Type::Constrained {
2449 base_type,
2450 constraint,
2451 } = &def.ty
2452 {
2453 assert!(matches!(base_type.as_ref(), Type::Integer(None, _)));
2454 if let ConstraintSpec::Subtype(SubtypeConstraint::ValueRange { min, max }) =
2455 &constraint.spec
2456 {
2457 assert_eq!(*min, ConstraintValue::Integer(-2147483648));
2458 assert_eq!(*max, ConstraintValue::Integer(2147483647));
2459 } else {
2460 panic!("Expected SubtypeConstraint::ValueRange");
2461 }
2462 } else {
2463 panic!("Expected Constrained type");
2464 }
2465 }
2466
2467 #[test]
2468 fn test_parse_value_constraint_single() {
2469 let input = r#"
2470 TestModule DEFINITIONS ::= BEGIN
2471 FixedValue ::= INTEGER (42)
2472 END
2473 "#;
2474
2475 let module = parse(input).unwrap();
2476 let def = &module.definitions[0];
2477
2478 if let Type::Constrained {
2480 base_type,
2481 constraint,
2482 } = &def.ty
2483 {
2484 assert!(matches!(base_type.as_ref(), Type::Integer(None, _)));
2485 if let ConstraintSpec::Subtype(SubtypeConstraint::SingleValue(val)) = &constraint.spec {
2486 assert_eq!(*val, ConstraintValue::Integer(42));
2487 } else {
2488 panic!("Expected SubtypeConstraint::SingleValue");
2489 }
2490 } else {
2491 panic!("Expected Constrained type");
2492 }
2493 }
2494
2495 #[test]
2496 fn test_parse_size_constraint() {
2497 let input = r#"
2500TestModule DEFINITIONS ::= BEGIN
2501 ShortString ::= OCTET STRING
2502END
2503 "#;
2504
2505 let module = parse(input).unwrap();
2506 let def = &module.definitions[0];
2507
2508 assert!(matches!(def.ty, Type::OctetString(_)));
2510 }
2511
2512 #[test]
2515 fn test_parse_constraint_value_min_max() {
2516 let mut parser = Parser::new("MIN..MAX").unwrap();
2517
2518 let value1 = parser.parse_constraint_value().unwrap();
2519 assert_eq!(value1, ConstraintValue::Min);
2520
2521 parser.expect_symbol("..").unwrap();
2522
2523 let value2 = parser.parse_constraint_value().unwrap();
2524 assert_eq!(value2, ConstraintValue::Max);
2525 }
2526
2527 #[test]
2528 fn test_parse_constraint_value_integer() {
2529 let mut parser = Parser::new("42").unwrap();
2530
2531 let value = parser.parse_constraint_value().unwrap();
2532 assert_eq!(value, ConstraintValue::Integer(42));
2533 }
2534
2535 #[test]
2536 fn test_parse_constraint_value_negative() {
2537 let mut parser = Parser::new("-100").unwrap();
2538
2539 let value = parser.parse_constraint_value().unwrap();
2540 assert_eq!(value, ConstraintValue::Integer(-100));
2541 }
2542
2543 #[test]
2544 fn test_parse_constraint_value_named() {
2545 let mut parser = Parser::new("maxValue").unwrap();
2546
2547 let value = parser.parse_constraint_value().unwrap();
2548 assert_eq!(value, ConstraintValue::NamedValue("maxValue".to_string()));
2549 }
2550
2551 #[test]
2552 fn test_parse_single_value_constraint() {
2553 let mut parser = Parser::new("42").unwrap();
2554
2555 let constraint = parser.parse_single_constraint().unwrap();
2556 assert_eq!(
2557 constraint,
2558 SubtypeConstraint::SingleValue(ConstraintValue::Integer(42))
2559 );
2560 }
2561
2562 #[test]
2563 fn test_parse_value_range_constraint() {
2564 let mut parser = Parser::new("0..100").unwrap();
2565
2566 let constraint = parser.parse_single_constraint().unwrap();
2567 assert!(matches!(constraint, SubtypeConstraint::ValueRange { .. }));
2568 }
2569
2570 #[test]
2571 fn test_parse_min_max_range() {
2572 let mut parser = Parser::new("MIN..MAX").unwrap();
2573
2574 let constraint = parser.parse_single_constraint().unwrap();
2575 if let SubtypeConstraint::ValueRange { min, max } = constraint {
2576 assert_eq!(min, ConstraintValue::Min);
2577 assert_eq!(max, ConstraintValue::Max);
2578 } else {
2579 panic!("Expected ValueRange constraint");
2580 }
2581 }
2582
2583 #[test]
2584 fn test_parse_union_constraint() {
2585 let mut parser = Parser::new("1 | 2 | 3").unwrap();
2586
2587 let constraint = parser.parse_subtype_constraint().unwrap();
2588 if let SubtypeConstraint::Union(elements) = constraint {
2589 assert_eq!(elements.len(), 3);
2590 } else {
2591 panic!("Expected Union constraint");
2592 }
2593 }
2594
2595 #[test]
2596 fn test_parse_intersection_constraint() {
2597 let mut parser = Parser::new("(0..100) ^ (10 | 20 | 30)").unwrap();
2598
2599 let constraint = parser.parse_subtype_constraint().unwrap();
2600 if let SubtypeConstraint::Intersection(elements) = constraint {
2601 assert_eq!(elements.len(), 2);
2602 } else {
2603 panic!("Expected Intersection constraint");
2604 }
2605 }
2606
2607 #[test]
2608 fn test_parse_complement_constraint() {
2609 let mut parser = Parser::new("ALL EXCEPT 0").unwrap();
2610
2611 let constraint = parser.parse_single_constraint().unwrap();
2612 if let SubtypeConstraint::Complement(inner) = constraint {
2613 assert_eq!(
2614 *inner,
2615 SubtypeConstraint::SingleValue(ConstraintValue::Integer(0))
2616 );
2617 } else {
2618 panic!("Expected Complement constraint");
2619 }
2620 }
2621
2622 #[test]
2623 fn test_parse_pattern_constraint() {
2624 let input = r#"
2625TestModule DEFINITIONS ::= BEGIN
2626 EmailPattern ::= IA5String (PATTERN "[a-z]+@[a-z]+\.[a-z]+")
2627END
2628 "#;
2629
2630 let module = parse(input).unwrap();
2631 assert_eq!(module.definitions.len(), 1);
2632
2633 let def = &module.definitions[0];
2634 assert_eq!(def.name, "EmailPattern");
2635
2636 if let Type::Constrained {
2638 base_type,
2639 constraint,
2640 } = &def.ty
2641 {
2642 assert!(
2644 matches!(base_type.as_ref(), Type::IA5String(_))
2645 || matches!(base_type.as_ref(), Type::TypeRef(s) if s == "IA5String")
2646 );
2647 if let ConstraintSpec::Subtype(SubtypeConstraint::Pattern(pattern)) = &constraint.spec {
2648 assert_eq!(pattern, "[a-z]+@[a-z]+.[a-z]+");
2650 } else {
2651 panic!("Expected Pattern constraint");
2652 }
2653 } else {
2654 panic!("Expected Constrained type");
2655 }
2656 }
2657
2658 #[test]
2659 fn test_parse_permitted_alphabet() {
2660 let input = r#"
2661TestModule DEFINITIONS ::= BEGIN
2662 MyNumericString ::= IA5String (FROM ("0".."9"))
2663END
2664 "#;
2665
2666 let module = parse(input).unwrap();
2667 let def = &module.definitions[0];
2668
2669 if let Type::Constrained { constraint, .. } = &def.ty {
2670 if let ConstraintSpec::Subtype(SubtypeConstraint::PermittedAlphabet(ranges)) =
2671 &constraint.spec
2672 {
2673 assert_eq!(ranges.len(), 1);
2674 assert_eq!(ranges[0].min, '0');
2675 assert_eq!(ranges[0].max, '9');
2676 } else {
2677 panic!("Expected PermittedAlphabet constraint");
2678 }
2679 } else {
2680 panic!("Expected Constrained type");
2681 }
2682 }
2683
2684 #[test]
2685 fn test_parse_containing_constraint() {
2686 let input = r#"
2687TestModule DEFINITIONS ::= BEGIN
2688 EncodedCert ::= OCTET STRING (CONTAINING INTEGER)
2689END
2690 "#;
2691
2692 let module = parse(input).unwrap();
2693 let def = &module.definitions[0];
2694
2695 if let Type::Constrained { constraint, .. } = &def.ty {
2696 if let ConstraintSpec::Subtype(SubtypeConstraint::ContainedSubtype(inner_type)) =
2697 &constraint.spec
2698 {
2699 assert!(matches!(inner_type.as_ref(), Type::Integer(_, _)));
2700 } else {
2701 panic!("Expected ContainedSubtype constraint");
2702 }
2703 } else {
2704 panic!("Expected Constrained type");
2705 }
2706 }
2707
2708 #[test]
2709 fn test_parse_inner_type_constraint() {
2710 let input = r#"
2711TestModule DEFINITIONS ::= BEGIN
2712 PositiveList ::= SEQUENCE OF INTEGER (1..MAX)
2713END
2714 "#;
2715
2716 let module = parse(input).unwrap();
2717 let def = &module.definitions[0];
2718
2719 if let Type::SequenceOf(inner_type, _) = &def.ty {
2721 if let Type::Constrained {
2723 base_type,
2724 constraint,
2725 } = inner_type.as_ref()
2726 {
2727 assert!(matches!(base_type.as_ref(), Type::Integer(_, _)));
2728 if let ConstraintSpec::Subtype(SubtypeConstraint::ValueRange { min, max }) =
2729 &constraint.spec
2730 {
2731 assert_eq!(*min, ConstraintValue::Integer(1));
2732 assert_eq!(*max, ConstraintValue::Max);
2733 } else {
2734 panic!("Expected ValueRange constraint on inner type");
2735 }
2736 } else {
2737 panic!("Expected inner type to be Constrained");
2738 }
2739 } else {
2740 panic!("Expected SequenceOf type, got: {:?}", def.ty);
2741 }
2742 }
2743
2744 #[test]
2745 fn test_parse_complex_nested_union() {
2746 let input = r#"
2747TestModule DEFINITIONS ::= BEGIN
2748 ComplexRange ::= INTEGER (0..10 | 20..30 | 40..50)
2749END
2750 "#;
2751
2752 let module = parse(input).unwrap();
2753 let def = &module.definitions[0];
2754
2755 if let Type::Constrained { constraint, .. } = &def.ty {
2756 if let ConstraintSpec::Subtype(SubtypeConstraint::Union(elements)) = &constraint.spec {
2757 assert_eq!(elements.len(), 3);
2758 for element in elements {
2759 assert!(matches!(element, SubtypeConstraint::ValueRange { .. }));
2760 }
2761 } else {
2762 panic!("Expected Union constraint");
2763 }
2764 } else {
2765 panic!("Expected Constrained type");
2766 }
2767 }
2768
2769 #[test]
2770 fn test_parse_nested_parentheses() {
2771 let input = r#"
2772TestModule DEFINITIONS ::= BEGIN
2773 Nested ::= INTEGER ((0..10) | (20..30))
2774END
2775 "#;
2776
2777 let module = parse(input).unwrap();
2778 let def = &module.definitions[0];
2779
2780 if let Type::Constrained { constraint, .. } = &def.ty {
2781 if let ConstraintSpec::Subtype(SubtypeConstraint::Union(elements)) = &constraint.spec {
2782 assert_eq!(elements.len(), 2);
2783 } else {
2784 panic!("Expected Union constraint");
2785 }
2786 } else {
2787 panic!("Expected Constrained type");
2788 }
2789 }
2790
2791 #[test]
2792 fn test_parse_size_constraint_on_string() {
2793 let input = r#"
2794TestModule DEFINITIONS ::= BEGIN
2795 ShortString ::= IA5String (SIZE (1..64))
2796END
2797 "#;
2798
2799 let result = parse(input);
2800 if let Err(e) = &result {
2801 println!("Parse error: {}", e);
2802 }
2803 let module = result.unwrap();
2804 let def = &module.definitions[0];
2805
2806 assert_eq!(def.name, "ShortString");
2807 if let Type::Constrained {
2809 base_type,
2810 constraint,
2811 } = &def.ty
2812 {
2813 println!("base_type: {:?}", base_type);
2816 assert!(
2818 matches!(base_type.as_ref(), Type::IA5String(None))
2819 || matches!(base_type.as_ref(), Type::TypeRef(s) if s == "IA5String")
2820 );
2821 if let ConstraintSpec::Subtype(SubtypeConstraint::SizeConstraint(inner)) =
2822 &constraint.spec
2823 {
2824 if let SubtypeConstraint::ValueRange { min, max } = inner.as_ref() {
2826 assert_eq!(*min, ConstraintValue::Integer(1));
2827 assert_eq!(*max, ConstraintValue::Integer(64));
2828 } else {
2829 panic!("Expected ValueRange inside SIZE constraint");
2830 }
2831 } else {
2832 panic!("Expected SizeConstraint, got {:?}", constraint.spec);
2833 }
2834 } else {
2835 panic!("Expected Constrained type, got {:?}", def.ty);
2836 }
2837 }
2838}