Add comma list to use tree

This commit is contained in:
Aleksey Kladov 2020-07-30 14:06:04 +02:00
parent 9042009b7f
commit e381c02ef3
3 changed files with 126 additions and 89 deletions

View file

@ -543,6 +543,10 @@ fn lower_enum(grammar: &Grammar, rule: &Rule) -> Option<Vec<String>> {
}
fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) {
if lower_comma_list(acc, grammar, rule) {
return;
}
match rule {
Rule::Node(node) => {
let field = Field::Node { name: grammar[*node].name.clone(), src: FieldSrc::Shorthand };
@ -595,6 +599,37 @@ fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) {
}
}
// (T (',' T)* ','?)?
fn lower_comma_list(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) -> bool {
let rule = match rule {
Rule::Opt(it) => it,
_ => return false,
};
let rule = match &**rule {
Rule::Seq(it) => it,
_ => return false,
};
let (node, repeat, trailing_comma) = match rule.as_slice() {
[Rule::Node(node), Rule::Rep(repeat), Rule::Opt(trailing_comma)] => {
(node, repeat, trailing_comma)
}
_ => return false,
};
let repeat = match &**repeat {
Rule::Seq(it) => it,
_ => return false,
};
match repeat.as_slice() {
[comma, Rule::Node(n)] if comma == &**trailing_comma && n == node => (),
_ => return false,
}
let name = grammar[*node].name.clone();
let label = pluralize(&to_lower_snake_case(&name));
let field = Field::Node { name: label.clone(), src: FieldSrc::Many(name) };
acc.push(field);
true
}
fn deduplicate_fields(ast: &mut AstSrc) {
for node in &mut ast.nodes {
let mut i = 0;

View file

@ -29,6 +29,19 @@ ItemList =
ExternCrate =
Attr* Visibility? 'extern' 'crate' (NameRef | 'self') Rename? ';'
Rename =
'as' (Name | '_')
UseItem =
Attr* Visibility? 'use' UseTree ';'
UseTree =
(Path? '::')? ('*' | UseTreeList )
| Path Rename?
UseTreeList =
'{' (UseTree (',' UseTree)* ','?)? '}'
FnDef =
Attr* Visibility? Abi? 'const' 'default' 'async' 'unsafe' 'fn' Name TypeParamList?
ParamList RetType?
@ -395,18 +408,6 @@ Param =
Attr* Pat (':' ascribed_type:TypeRef)
| '...'
UseItem =
Attr* Visibility? 'use' UseTree ';'
UseTree =
Path ('::' ('*' | UseTreeList)) Rename?
UseTreeList =
'{' UseTree* '}'
Rename =
'as' Name
Path =
(qualifier:Path '::')? segment:PathSegment