fix(generate): filter out unused rules in other spots
This commit is contained in:
parent
e4dec3d3d8
commit
49bda0e2c5
2 changed files with 52 additions and 46 deletions
|
|
@ -110,8 +110,7 @@ fn rule_is_referenced(rule: &Rule, target: &str) -> bool {
|
|||
|
||||
fn variable_is_used(
|
||||
grammar_rules: &[(String, Rule)],
|
||||
extras: &[Rule],
|
||||
externals: &[Rule],
|
||||
other_rules: (&[Rule], &[Rule]),
|
||||
target_name: &str,
|
||||
in_progress: &mut HashSet<String>,
|
||||
) -> bool {
|
||||
|
|
@ -120,9 +119,10 @@ fn variable_is_used(
|
|||
return true;
|
||||
}
|
||||
|
||||
if extras
|
||||
if other_rules
|
||||
.0
|
||||
.iter()
|
||||
.chain(externals.iter())
|
||||
.chain(other_rules.1.iter())
|
||||
.any(|rule| rule_is_referenced(rule, target_name))
|
||||
{
|
||||
return true;
|
||||
|
|
@ -136,7 +136,7 @@ fn variable_is_used(
|
|||
if !rule_is_referenced(rule, target_name) || in_progress.contains(name) {
|
||||
return false;
|
||||
}
|
||||
variable_is_used(grammar_rules, extras, externals, name, in_progress)
|
||||
variable_is_used(grammar_rules, other_rules, name, in_progress)
|
||||
});
|
||||
in_progress.remove(target_name);
|
||||
|
||||
|
|
@ -169,36 +169,6 @@ pub(crate) fn parse_grammar(input: &str) -> Result<InputGrammar> {
|
|||
.map(parse_rule)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut variables = Vec::with_capacity(grammar_json.rules.len());
|
||||
|
||||
let rules = grammar_json
|
||||
.rules
|
||||
.into_iter()
|
||||
.map(|(n, r)| Ok((n, parse_rule(serde_json::from_value(r)?))))
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
||||
let mut in_progress = HashSet::new();
|
||||
|
||||
for (name, rule) in &rules {
|
||||
if !variable_is_used(
|
||||
&rules,
|
||||
&extra_symbols,
|
||||
&external_tokens,
|
||||
name,
|
||||
&mut in_progress,
|
||||
) {
|
||||
extra_symbols.retain(|r| !rule_is_referenced(r, name));
|
||||
external_tokens.retain(|r| !rule_is_referenced(r, name));
|
||||
grammar_json.supertypes.retain(|r| r != name);
|
||||
continue;
|
||||
}
|
||||
variables.push(Variable {
|
||||
name: name.clone(),
|
||||
kind: VariableType::Named,
|
||||
rule: rule.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
let mut precedence_orderings = Vec::with_capacity(grammar_json.precedences.len());
|
||||
for list in grammar_json.precedences {
|
||||
let mut ordering = Vec::with_capacity(list.len());
|
||||
|
|
@ -216,6 +186,46 @@ pub(crate) fn parse_grammar(input: &str) -> Result<InputGrammar> {
|
|||
precedence_orderings.push(ordering);
|
||||
}
|
||||
|
||||
let mut variables = Vec::with_capacity(grammar_json.rules.len());
|
||||
|
||||
let rules = grammar_json
|
||||
.rules
|
||||
.into_iter()
|
||||
.map(|(n, r)| Ok((n, parse_rule(serde_json::from_value(r)?))))
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
||||
let mut in_progress = HashSet::new();
|
||||
|
||||
for (name, rule) in &rules {
|
||||
if !variable_is_used(
|
||||
&rules,
|
||||
(&extra_symbols, &external_tokens),
|
||||
name,
|
||||
&mut in_progress,
|
||||
) && grammar_json.word.as_ref().map_or(true, |w| w != name)
|
||||
{
|
||||
grammar_json.conflicts.retain(|r| !r.contains(name));
|
||||
grammar_json.supertypes.retain(|r| r != name);
|
||||
grammar_json.inline.retain(|r| r != name);
|
||||
extra_symbols.retain(|r| !rule_is_referenced(r, name));
|
||||
external_tokens.retain(|r| !rule_is_referenced(r, name));
|
||||
precedence_orderings.retain(|r| {
|
||||
!r.iter().any(|e| {
|
||||
let PrecedenceEntry::Symbol(s) = e else {
|
||||
return false;
|
||||
};
|
||||
s == name
|
||||
})
|
||||
});
|
||||
continue;
|
||||
}
|
||||
variables.push(Variable {
|
||||
name: name.clone(),
|
||||
kind: VariableType::Named,
|
||||
rule: rule.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
Ok(InputGrammar {
|
||||
name: grammar_json.name,
|
||||
word_token: grammar_json.word,
|
||||
|
|
|
|||
|
|
@ -40,22 +40,18 @@ pub(super) fn intern_symbols(grammar: &InputGrammar) -> Result<InternedGrammar>
|
|||
|
||||
let mut supertype_symbols = Vec::with_capacity(grammar.supertype_symbols.len());
|
||||
for supertype_symbol_name in &grammar.supertype_symbols {
|
||||
supertype_symbols.push(
|
||||
interner
|
||||
.intern_name(supertype_symbol_name)
|
||||
.ok_or_else(|| anyhow!("Undefined symbol `{supertype_symbol_name}`"))?,
|
||||
);
|
||||
supertype_symbols.push(interner.intern_name(supertype_symbol_name).ok_or_else(|| {
|
||||
anyhow!("Undefined symbol `{supertype_symbol_name}` in grammar's supertypes array")
|
||||
})?);
|
||||
}
|
||||
|
||||
let mut expected_conflicts = Vec::new();
|
||||
for conflict in &grammar.expected_conflicts {
|
||||
let mut interned_conflict = Vec::with_capacity(conflict.len());
|
||||
for name in conflict {
|
||||
interned_conflict.push(
|
||||
interner
|
||||
.intern_name(name)
|
||||
.ok_or_else(|| anyhow!("Undefined symbol `{name}`"))?,
|
||||
);
|
||||
interned_conflict.push(interner.intern_name(name).ok_or_else(|| {
|
||||
anyhow!("Undefined symbol `{name}` in grammar's conflicts array")
|
||||
})?);
|
||||
}
|
||||
expected_conflicts.push(interned_conflict);
|
||||
}
|
||||
|
|
@ -72,7 +68,7 @@ pub(super) fn intern_symbols(grammar: &InputGrammar) -> Result<InternedGrammar>
|
|||
word_token = Some(
|
||||
interner
|
||||
.intern_name(name)
|
||||
.ok_or_else(|| anyhow!("Undefined symbol `{name}`"))?,
|
||||
.ok_or_else(|| anyhow!("Undefined symbol `{name}` as grammar's word token"))?,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue