@@ -409,16 +409,20 @@ impl<'a> Parser<'a> {
409
409
range : ( usize , usize ) ,
410
410
}
411
411
412
- let mut unknown_rules = Vec :: default ( ) ;
412
+ // First pass: Parse all rules and register their names without checking for unknown identifiers
413
+ let mut all_rules = Vec :: default ( ) ;
414
+ // let mut rule_ranges = Vec::default();
413
415
414
416
while self . cur_token != Token :: EOF {
415
417
let begin_rule_range = self . lexer_position . range . 0 ;
418
+
416
419
match self . parse_rule ( false ) {
417
420
Ok ( r) => {
418
421
let rule_exists =
419
422
|existing_rule : & Rule | r. name ( ) == existing_rule. name ( ) && !r. is_choice_alternate ( ) ;
420
423
421
- if c. rules . iter ( ) . any ( rule_exists) {
424
+ if c. rules . iter ( ) . any ( rule_exists) || all_rules. iter ( ) . any ( |( rule, _) | rule_exists ( rule) )
425
+ {
422
426
#[ cfg( feature = "ast-span" ) ]
423
427
{
424
428
self . parser_position . range = ( r. span ( ) . 0 , r. span ( ) . 1 ) ;
@@ -434,20 +438,10 @@ impl<'a> Parser<'a> {
434
438
continue ;
435
439
}
436
440
437
- if !self . unknown_rule_idents . is_empty ( ) {
438
- if self . is_guaranteed {
439
- self . register_rule ( & r) ;
440
- }
441
- unknown_rules. push ( UnknownRule {
442
- rule : r,
443
- index : c. rules . len ( ) ,
444
- range : ( begin_rule_range, self . lexer_position . range . 1 ) ,
445
- } ) ;
446
- self . unknown_rule_idents = Vec :: default ( ) ;
447
- } else {
448
- self . register_rule ( & r) ;
449
- c. rules . push ( r) ;
450
- }
441
+ // Register the rule name immediately
442
+ self . register_rule ( & r) ;
443
+
444
+ all_rules. push ( ( r, begin_rule_range) ) ;
451
445
self . is_guaranteed = false ;
452
446
}
453
447
Err ( Error :: INCREMENTAL ) => {
@@ -459,6 +453,23 @@ impl<'a> Parser<'a> {
459
453
}
460
454
}
461
455
456
+ // Second pass: Add all rules to the CDDL
457
+ let mut unknown_rules = Vec :: default ( ) ;
458
+
459
+ for ( rule, begin_rule_range) in all_rules {
460
+ // Check if the rule still has unknown identifiers
461
+ if !self . unknown_rule_idents . is_empty ( ) {
462
+ unknown_rules. push ( UnknownRule {
463
+ rule,
464
+ index : c. rules . len ( ) ,
465
+ range : ( begin_rule_range, self . lexer_position . range . 1 ) ,
466
+ } ) ;
467
+ self . unknown_rule_idents = Vec :: default ( ) ;
468
+ } else {
469
+ c. rules . push ( rule) ;
470
+ }
471
+ }
472
+
462
473
// In practice unknown rules usually are declared backwards, so we reverse
463
474
// it here.
464
475
unknown_rules. reverse ( ) ;
@@ -3707,3 +3718,31 @@ pub fn format_cddl_from_str(input: &str) -> result::Result<String, JsValue> {
3707
3718
Err ( e) => Err ( JsValue :: from ( e. to_string ( ) ) ) ,
3708
3719
}
3709
3720
}
3721
+
3722
+ #[ cfg( test) ]
3723
+ mod tests {
3724
+ use super :: * ;
3725
+ use crate :: lexer;
3726
+
3727
+ #[ test]
3728
+ fn test_multiple_rules_with_reference_to_parenthesized_type ( ) {
3729
+ let input = r#"basic = (d: #6.23(uint), e: bytes)
3730
+ outer = [a: uint, b: basic, c: "some text"]"# ;
3731
+
3732
+ // Use the parser directly for better error diagnostics
3733
+ let mut parser = Parser :: new ( input, Box :: new ( lexer:: lexer_from_str ( input) . iter ( ) ) ) . unwrap ( ) ;
3734
+ let result = parser. parse_cddl ( ) ;
3735
+
3736
+ // Ensure there are no errors
3737
+ assert ! ( result. is_ok( ) , "Parser errors: {:?}" , parser. errors) ;
3738
+
3739
+ // Check that the CDDL contains two rules
3740
+ let cddl = result. unwrap ( ) ;
3741
+ assert_eq ! ( cddl. rules. len( ) , 2 ) ;
3742
+
3743
+ // Verify rule names
3744
+ let rule_names: Vec < _ > = cddl. rules . iter ( ) . map ( |r| r. name ( ) ) . collect ( ) ;
3745
+ assert ! ( rule_names. contains( & "basic" . to_string( ) ) ) ;
3746
+ assert ! ( rule_names. contains( & "outer" . to_string( ) ) ) ;
3747
+ }
3748
+ }
0 commit comments