aboutsummaryrefslogtreecommitdiff
path: root/xtask/src
diff options
context:
space:
mode:
Diffstat (limited to 'xtask/src')
-rw-r--r--xtask/src/ast_src.rs4
-rw-r--r--xtask/src/codegen/gen_syntax.rs58
-rw-r--r--xtask/src/codegen/rust.ungram7
3 files changed, 29 insertions, 40 deletions
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index 0e3d89a07..47e9d0c21 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -242,11 +242,11 @@ pub(crate) struct AstNodeSrc {
242#[derive(Debug, Eq, PartialEq)] 242#[derive(Debug, Eq, PartialEq)]
243pub(crate) enum Field { 243pub(crate) enum Field {
244 Token(String), 244 Token(String),
245 Node { name: String, ty: String, valence: Valence }, 245 Node { name: String, ty: String, cardinality: Cardinality },
246} 246}
247 247
248#[derive(Debug, Eq, PartialEq)] 248#[derive(Debug, Eq, PartialEq)]
249pub(crate) enum Valence { 249pub(crate) enum Cardinality {
250 Optional, 250 Optional,
251 Many, 251 Many,
252} 252}
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index b435d8a9c..84ddda5cb 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -13,7 +13,7 @@ use quote::{format_ident, quote};
13use ungrammar::{Grammar, Rule}; 13use ungrammar::{Grammar, Rule};
14 14
15use crate::{ 15use crate::{
16 ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Field, KindsSrc, Valence, KINDS_SRC}, 16 ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Cardinality, Field, KindsSrc, KINDS_SRC},
17 codegen::{self, update, Mode}, 17 codegen::{self, update, Mode},
18 project_root, Result, 18 project_root, Result,
19}; 19};
@@ -431,7 +431,7 @@ fn pluralize(s: &str) -> String {
431 431
432impl Field { 432impl Field {
433 fn is_many(&self) -> bool { 433 fn is_many(&self) -> bool {
434 matches!(self, Field::Node { valence: Valence::Many, .. }) 434 matches!(self, Field::Node { cardinality: Cardinality::Many, .. })
435 } 435 }
436 fn token_kind(&self) -> Option<proc_macro2::TokenStream> { 436 fn token_kind(&self) -> Option<proc_macro2::TokenStream> {
437 match self { 437 match self {
@@ -509,7 +509,7 @@ fn lower(grammar: &Grammar) -> AstSrc {
509 } 509 }
510 None => { 510 None => {
511 let mut fields = Vec::new(); 511 let mut fields = Vec::new();
512 lower_rule(&mut fields, grammar, rule); 512 lower_rule(&mut fields, grammar, None, rule);
513 res.nodes.push(AstNodeSrc { doc: Vec::new(), name, traits: Vec::new(), fields }); 513 res.nodes.push(AstNodeSrc { doc: Vec::new(), name, traits: Vec::new(), fields });
514 } 514 }
515 } 515 }
@@ -537,19 +537,20 @@ fn lower_enum(grammar: &Grammar, rule: &Rule) -> Option<Vec<String>> {
537 Some(variants) 537 Some(variants)
538} 538}
539 539
540fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) { 540fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, label: Option<&String>, rule: &Rule) {
541 if lower_comma_list(acc, grammar, rule) { 541 if lower_comma_list(acc, grammar, label, rule) {
542 return; 542 return;
543 } 543 }
544 544
545 match rule { 545 match rule {
546 Rule::Node(node) => { 546 Rule::Node(node) => {
547 let ty = grammar[*node].name.clone(); 547 let ty = grammar[*node].name.clone();
548 let name = to_lower_snake_case(&ty); 548 let name = label.cloned().unwrap_or_else(|| to_lower_snake_case(&ty));
549 let field = Field::Node { name, ty, valence: Valence::Optional }; 549 let field = Field::Node { name, ty, cardinality: Cardinality::Optional };
550 acc.push(field); 550 acc.push(field);
551 } 551 }
552 Rule::Token(token) => { 552 Rule::Token(token) => {
553 assert!(label.is_none());
553 let mut name = grammar[*token].name.clone(); 554 let mut name = grammar[*token].name.clone();
554 if name != "int_number" && name != "string" { 555 if name != "int_number" && name != "string" {
555 if "[]{}()".contains(&name) { 556 if "[]{}()".contains(&name) {
@@ -562,44 +563,33 @@ fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) {
562 Rule::Rep(inner) => { 563 Rule::Rep(inner) => {
563 if let Rule::Node(node) = &**inner { 564 if let Rule::Node(node) = &**inner {
564 let ty = grammar[*node].name.clone(); 565 let ty = grammar[*node].name.clone();
565 let name = pluralize(&to_lower_snake_case(&ty)); 566 let name = label.cloned().unwrap_or_else(|| pluralize(&to_lower_snake_case(&ty)));
566 let field = Field::Node { name, ty, valence: Valence::Many }; 567 let field = Field::Node { name, ty, cardinality: Cardinality::Many };
567 acc.push(field); 568 acc.push(field);
568 return; 569 return;
569 } 570 }
570 todo!("{:?}", rule) 571 todo!("{:?}", rule)
571 } 572 }
572 Rule::Labeled { label, rule } => { 573 Rule::Labeled { label: l, rule } => {
573 let node = match &**rule { 574 assert!(label.is_none());
574 Rule::Rep(inner) | Rule::Opt(inner) => match &**inner { 575 lower_rule(acc, grammar, Some(l), rule);
575 Rule::Node(node) => node,
576 _ => todo!("{:?}", rule),
577 },
578 Rule::Node(node) => node,
579 _ => todo!("{:?}", rule),
580 };
581 let ty = grammar[*node].name.clone();
582 let field = Field::Node {
583 name: label.clone(),
584 ty,
585 valence: match &**rule {
586 Rule::Rep(_) => Valence::Many,
587 _ => Valence::Optional,
588 },
589 };
590 acc.push(field);
591 } 576 }
592 Rule::Seq(rules) | Rule::Alt(rules) => { 577 Rule::Seq(rules) | Rule::Alt(rules) => {
593 for rule in rules { 578 for rule in rules {
594 lower_rule(acc, grammar, rule) 579 lower_rule(acc, grammar, label, rule)
595 } 580 }
596 } 581 }
597 Rule::Opt(rule) => lower_rule(acc, grammar, rule), 582 Rule::Opt(rule) => lower_rule(acc, grammar, label, rule),
598 } 583 }
599} 584}
600 585
601// (T (',' T)* ','?) 586// (T (',' T)* ','?)
602fn lower_comma_list(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) -> bool { 587fn lower_comma_list(
588 acc: &mut Vec<Field>,
589 grammar: &Grammar,
590 label: Option<&String>,
591 rule: &Rule,
592) -> bool {
603 let rule = match rule { 593 let rule = match rule {
604 Rule::Seq(it) => it, 594 Rule::Seq(it) => it,
605 _ => return false, 595 _ => return false,
@@ -619,8 +609,8 @@ fn lower_comma_list(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) -> boo
619 _ => return false, 609 _ => return false,
620 } 610 }
621 let ty = grammar[*node].name.clone(); 611 let ty = grammar[*node].name.clone();
622 let name = pluralize(&to_lower_snake_case(&ty)); 612 let name = label.cloned().unwrap_or_else(|| pluralize(&to_lower_snake_case(&ty)));
623 let field = Field::Node { name, ty, valence: Valence::Many }; 613 let field = Field::Node { name, ty, cardinality: Cardinality::Many };
624 acc.push(field); 614 acc.push(field);
625 true 615 true
626} 616}
@@ -656,7 +646,7 @@ fn extract_enums(ast: &mut AstSrc) {
656 node.remove_field(to_remove); 646 node.remove_field(to_remove);
657 let ty = enm.name.clone(); 647 let ty = enm.name.clone();
658 let name = to_lower_snake_case(&ty); 648 let name = to_lower_snake_case(&ty);
659 node.fields.push(Field::Node { name, ty, valence: Valence::Optional }); 649 node.fields.push(Field::Node { name, ty, cardinality: Cardinality::Optional });
660 } 650 }
661 } 651 }
662 } 652 }
diff --git a/xtask/src/codegen/rust.ungram b/xtask/src/codegen/rust.ungram
index ba922af0d..28b50f021 100644
--- a/xtask/src/codegen/rust.ungram
+++ b/xtask/src/codegen/rust.ungram
@@ -83,22 +83,21 @@ StructDef =
83 ) 83 )
84 84
85RecordFieldList = 85RecordFieldList =
86 '{' fields:RecordField* '}' 86 '{' fields:(RecordField (',' RecordField)* ','?)? '}'
87 87
88RecordField = 88RecordField =
89 Attr* Visibility? Name ':' ascribed_type:TypeRef 89 Attr* Visibility? Name ':' ascribed_type:TypeRef
90 90
91TupleFieldList = 91TupleFieldList =
92 '(' fields:TupleField* ')' 92 '(' fields:(TupleField (',' TupleField)* ','?)? ')'
93 93
94TupleField = 94TupleField =
95 Attr* Visibility? Name TypeRef 95 Attr* Visibility? TypeRef
96 96
97FieldList = 97FieldList =
98 RecordFieldList 98 RecordFieldList
99| TupleFieldList 99| TupleFieldList
100 100
101
102UnionDef = 101UnionDef =
103 Attr* Visibility? 'union' Name GenericParamList? WhereClause? 102 Attr* Visibility? 'union' Name GenericParamList? WhereClause?
104 RecordFieldList 103 RecordFieldList