diff options
-rw-r--r-- | xtask/src/ast_src.rs | 4 | ||||
-rw-r--r-- | xtask/src/codegen/gen_syntax.rs | 58 |
2 files changed, 26 insertions, 36 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)] |
243 | pub(crate) enum Field { | 243 | pub(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)] |
249 | pub(crate) enum Valence { | 249 | pub(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}; | |||
13 | use ungrammar::{Grammar, Rule}; | 13 | use ungrammar::{Grammar, Rule}; |
14 | 14 | ||
15 | use crate::{ | 15 | use 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 | ||
432 | impl Field { | 432 | impl 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 | ||
540 | fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) { | 540 | fn 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)* ','?) |
602 | fn lower_comma_list(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) -> bool { | 587 | fn 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 | } |