Skip to content

Commit dd24c8c

Browse files
authored
Merge pull request #247 from anweiss/fix-222
Fix parsing errors
2 parents 571abae + 6f68909 commit dd24c8c

File tree

2 files changed

+55
-19
lines changed

2 files changed

+55
-19
lines changed

.github/workflows/anchore.yml

-3
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ name: Anchore Grype vulnerability scan
1414
on:
1515
push:
1616
branches: [ "main" ]
17-
pull_request:
18-
# The branches below must be a subset of the branches above
19-
branches: [ "main" ]
2017
schedule:
2118
- cron: '26 1 * * 5'
2219

src/parser.rs

+55-16
Original file line numberDiff line numberDiff line change
@@ -409,16 +409,20 @@ impl<'a> Parser<'a> {
409409
range: (usize, usize),
410410
}
411411

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();
413415

414416
while self.cur_token != Token::EOF {
415417
let begin_rule_range = self.lexer_position.range.0;
418+
416419
match self.parse_rule(false) {
417420
Ok(r) => {
418421
let rule_exists =
419422
|existing_rule: &Rule| r.name() == existing_rule.name() && !r.is_choice_alternate();
420423

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+
{
422426
#[cfg(feature = "ast-span")]
423427
{
424428
self.parser_position.range = (r.span().0, r.span().1);
@@ -434,20 +438,10 @@ impl<'a> Parser<'a> {
434438
continue;
435439
}
436440

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));
451445
self.is_guaranteed = false;
452446
}
453447
Err(Error::INCREMENTAL) => {
@@ -459,6 +453,23 @@ impl<'a> Parser<'a> {
459453
}
460454
}
461455

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+
462473
// In practice unknown rules usually are declared backwards, so we reverse
463474
// it here.
464475
unknown_rules.reverse();
@@ -3707,3 +3718,31 @@ pub fn format_cddl_from_str(input: &str) -> result::Result<String, JsValue> {
37073718
Err(e) => Err(JsValue::from(e.to_string())),
37083719
}
37093720
}
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

Comments
 (0)