5600: Finalize structs grammar r=matklad a=matklad



bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2020-07-30 15:29:05 +00:00 committed by GitHub
commit 2496628c56
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 41 deletions

View file

@ -422,7 +422,6 @@ pub struct TupleField {
pub(crate) syntax: SyntaxNode, pub(crate) syntax: SyntaxNode,
} }
impl ast::AttrsOwner for TupleField {} impl ast::AttrsOwner for TupleField {}
impl ast::NameOwner for TupleField {}
impl ast::VisibilityOwner for TupleField {} impl ast::VisibilityOwner for TupleField {}
impl TupleField { impl TupleField {
pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) } pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }

View file

@ -242,11 +242,11 @@ pub(crate) struct AstNodeSrc {
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub(crate) enum Field { pub(crate) enum Field {
Token(String), Token(String),
Node { name: String, ty: String, valence: Valence }, Node { name: String, ty: String, cardinality: Cardinality },
} }
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub(crate) enum Valence { pub(crate) enum Cardinality {
Optional, Optional,
Many, Many,
} }

View file

@ -13,7 +13,7 @@ use quote::{format_ident, quote};
use ungrammar::{Grammar, Rule}; use ungrammar::{Grammar, Rule};
use crate::{ use crate::{
ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Field, KindsSrc, Valence, KINDS_SRC}, ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Cardinality, Field, KindsSrc, KINDS_SRC},
codegen::{self, update, Mode}, codegen::{self, update, Mode},
project_root, Result, project_root, Result,
}; };
@ -431,7 +431,7 @@ fn pluralize(s: &str) -> String {
impl Field { impl Field {
fn is_many(&self) -> bool { fn is_many(&self) -> bool {
matches!(self, Field::Node { valence: Valence::Many, .. }) matches!(self, Field::Node { cardinality: Cardinality::Many, .. })
} }
fn token_kind(&self) -> Option<proc_macro2::TokenStream> { fn token_kind(&self) -> Option<proc_macro2::TokenStream> {
match self { match self {
@ -509,7 +509,7 @@ fn lower(grammar: &Grammar) -> AstSrc {
} }
None => { None => {
let mut fields = Vec::new(); let mut fields = Vec::new();
lower_rule(&mut fields, grammar, rule); lower_rule(&mut fields, grammar, None, rule);
res.nodes.push(AstNodeSrc { doc: Vec::new(), name, traits: Vec::new(), fields }); res.nodes.push(AstNodeSrc { doc: Vec::new(), name, traits: Vec::new(), fields });
} }
} }
@ -537,19 +537,20 @@ fn lower_enum(grammar: &Grammar, rule: &Rule) -> Option<Vec<String>> {
Some(variants) Some(variants)
} }
fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) { fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, label: Option<&String>, rule: &Rule) {
if lower_comma_list(acc, grammar, rule) { if lower_comma_list(acc, grammar, label, rule) {
return; return;
} }
match rule { match rule {
Rule::Node(node) => { Rule::Node(node) => {
let ty = grammar[*node].name.clone(); let ty = grammar[*node].name.clone();
let name = to_lower_snake_case(&ty); let name = label.cloned().unwrap_or_else(|| to_lower_snake_case(&ty));
let field = Field::Node { name, ty, valence: Valence::Optional }; let field = Field::Node { name, ty, cardinality: Cardinality::Optional };
acc.push(field); acc.push(field);
} }
Rule::Token(token) => { Rule::Token(token) => {
assert!(label.is_none());
let mut name = grammar[*token].name.clone(); let mut name = grammar[*token].name.clone();
if name != "int_number" && name != "string" { if name != "int_number" && name != "string" {
if "[]{}()".contains(&name) { if "[]{}()".contains(&name) {
@ -562,44 +563,33 @@ fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) {
Rule::Rep(inner) => { Rule::Rep(inner) => {
if let Rule::Node(node) = &**inner { if let Rule::Node(node) = &**inner {
let ty = grammar[*node].name.clone(); let ty = grammar[*node].name.clone();
let name = pluralize(&to_lower_snake_case(&ty)); let name = label.cloned().unwrap_or_else(|| pluralize(&to_lower_snake_case(&ty)));
let field = Field::Node { name, ty, valence: Valence::Many }; let field = Field::Node { name, ty, cardinality: Cardinality::Many };
acc.push(field); acc.push(field);
return; return;
} }
todo!("{:?}", rule) todo!("{:?}", rule)
} }
Rule::Labeled { label, rule } => { Rule::Labeled { label: l, rule } => {
let node = match &**rule { assert!(label.is_none());
Rule::Rep(inner) | Rule::Opt(inner) => match &**inner { lower_rule(acc, grammar, Some(l), rule);
Rule::Node(node) => node,
_ => todo!("{:?}", rule),
},
Rule::Node(node) => node,
_ => todo!("{:?}", rule),
};
let ty = grammar[*node].name.clone();
let field = Field::Node {
name: label.clone(),
ty,
valence: match &**rule {
Rule::Rep(_) => Valence::Many,
_ => Valence::Optional,
},
};
acc.push(field);
} }
Rule::Seq(rules) | Rule::Alt(rules) => { Rule::Seq(rules) | Rule::Alt(rules) => {
for rule in rules { for rule in rules {
lower_rule(acc, grammar, rule) lower_rule(acc, grammar, label, rule)
} }
} }
Rule::Opt(rule) => lower_rule(acc, grammar, rule), Rule::Opt(rule) => lower_rule(acc, grammar, label, rule),
} }
} }
// (T (',' T)* ','?) // (T (',' T)* ','?)
fn lower_comma_list(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) -> bool { fn lower_comma_list(
acc: &mut Vec<Field>,
grammar: &Grammar,
label: Option<&String>,
rule: &Rule,
) -> bool {
let rule = match rule { let rule = match rule {
Rule::Seq(it) => it, Rule::Seq(it) => it,
_ => return false, _ => return false,
@ -619,8 +609,8 @@ fn lower_comma_list(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) -> boo
_ => return false, _ => return false,
} }
let ty = grammar[*node].name.clone(); let ty = grammar[*node].name.clone();
let name = pluralize(&to_lower_snake_case(&ty)); let name = label.cloned().unwrap_or_else(|| pluralize(&to_lower_snake_case(&ty)));
let field = Field::Node { name, ty, valence: Valence::Many }; let field = Field::Node { name, ty, cardinality: Cardinality::Many };
acc.push(field); acc.push(field);
true true
} }
@ -656,7 +646,7 @@ fn extract_enums(ast: &mut AstSrc) {
node.remove_field(to_remove); node.remove_field(to_remove);
let ty = enm.name.clone(); let ty = enm.name.clone();
let name = to_lower_snake_case(&ty); let name = to_lower_snake_case(&ty);
node.fields.push(Field::Node { name, ty, valence: Valence::Optional }); node.fields.push(Field::Node { name, ty, cardinality: Cardinality::Optional });
} }
} }
} }

View file

@ -83,22 +83,21 @@ StructDef =
) )
RecordFieldList = RecordFieldList =
'{' fields:RecordField* '}' '{' fields:(RecordField (',' RecordField)* ','?)? '}'
RecordField = RecordField =
Attr* Visibility? Name ':' ascribed_type:TypeRef Attr* Visibility? Name ':' ascribed_type:TypeRef
TupleFieldList = TupleFieldList =
'(' fields:TupleField* ')' '(' fields:(TupleField (',' TupleField)* ','?)? ')'
TupleField = TupleField =
Attr* Visibility? Name TypeRef Attr* Visibility? TypeRef
FieldList = FieldList =
RecordFieldList RecordFieldList
| TupleFieldList | TupleFieldList
UnionDef = UnionDef =
Attr* Visibility? 'union' Name GenericParamList? WhereClause? Attr* Visibility? 'union' Name GenericParamList? WhereClause?
RecordFieldList RecordFieldList