Skip to content

Commit d6b34e8

Browse files
committed
[update] 1つの列挙子に対して複数の #rule を指定できるようにした
1 parent 78d215b commit d6b34e8

File tree

7 files changed

+41
-56
lines changed

7 files changed

+41
-56
lines changed

crates/algorithm_lr1/src/builder.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ where
3737
{
3838
pub fn setup() -> anyhow::Result<Self> {
3939
// 1. Pre-process
40+
let rules = S::into_iter().collect::<Vec<_>>();
4041
let ruleset = S::into_ruleset();
4142
let first_set = ruleset.first_set();
4243

@@ -81,7 +82,6 @@ where
8182
}
8283

8384
// 5. Setup tables
84-
let rule_table: Vec<S> = S::into_iter().collect();
8585
for lritem_set in &dfa.0 {
8686
for (token, next) in &lritem_set.next {
8787
match &token {
@@ -109,7 +109,7 @@ where
109109
let id = lritem_set.id as usize;
110110
let label = action_table[id].get_mut(&t.0).unwrap();
111111
*label = LRAction::Reduce(
112-
rule_table[item.rule.id as usize],
112+
rules[item.rule.id as usize],
113113
*nonterm_table.get(lhs).unwrap(),
114114
item.rule.rhs.len(),
115115
);
@@ -120,7 +120,7 @@ where
120120
LRAction::Accept
121121
} else {
122122
LRAction::Reduce(
123-
rule_table[item.rule.id as usize],
123+
rules[item.rule.id as usize],
124124
*nonterm_table.get(lhs).unwrap(),
125125
item.rule.rhs.len(),
126126
)

crates/algorithm_lr1/src/lib.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,19 +68,14 @@ mod test {
6868
#[derive(Debug, Clone, Copy, Syntax)]
6969
enum TestSyntax {
7070
#[rule("<expr> ::= <expr> Plus <term>")]
71-
ExprPlus,
7271
#[rule("<expr> ::= <expr> Minus <term>")]
73-
ExprMinus,
7472
#[rule("<expr> ::= <term>")]
75-
ExprTerm,
73+
Expr,
7674
#[rule("<term> ::= <term> Mul <num>")]
77-
TermMul,
7875
#[rule("<term> ::= <term> Div <num>")]
79-
TermDiv,
8076
#[rule("<term> ::= <num>")]
81-
TermNum,
77+
Term,
8278
#[rule("<num> ::= BracketL <expr> BracketR")]
83-
NestedNum,
8479
#[rule("<num> ::= Num")]
8580
Num,
8681
}

crates/core/src/cfg/syntax.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,18 @@ where
1212
type TokenSet: TokenSet<'a>;
1313

1414
fn into_iter() -> impl Iterator<Item = Self>;
15-
fn into_rule(&self) -> Rule<'a, Self::TokenSet>;
15+
fn into_rules(&self) -> Vec<Rule<'a, Self::TokenSet>>;
1616

1717
fn into_ruleset() -> RuleSet<'a, Self::TokenSet> {
1818
let rules = Self::into_iter()
19-
.map(|elem| Self::into_rule(&elem))
19+
.enumerate()
20+
.flat_map(|(idx, elem)| {
21+
let mut rules = Self::into_rules(&elem);
22+
for rule in &mut rules {
23+
rule.id = idx;
24+
}
25+
rules
26+
})
2027
.collect::<Vec<_>>();
2128

2229
RuleSet::from(rules)
@@ -110,16 +117,12 @@ pub struct RuleSet<'a, T: TokenSet<'a>> {
110117
}
111118

112119
impl<'a, T: TokenSet<'a>> From<Vec<Rule<'a, T>>> for RuleSet<'a, T> {
113-
fn from(mut rules: Vec<Rule<'a, T>>) -> Self {
120+
fn from(rules: Vec<Rule<'a, T>>) -> Self {
114121
let top = match &rules[0].lhs {
115122
RuleElem::NonTerm(s) => s.clone(),
116123
_ => unreachable!(),
117124
};
118125

119-
for (idx, rule) in rules.iter_mut().enumerate() {
120-
rule.id = idx;
121-
}
122-
123126
RuleSet {
124127
top,
125128
rules,
@@ -307,7 +310,7 @@ mod test {
307310
)
308311
}
309312

310-
fn into_rule(&self) -> Rule<'a, Self::TokenSet> {
313+
fn into_rules(&self) -> Vec<Rule<'a, Self::TokenSet>> {
311314
let expr_plus = Rule::from((
312315
RuleElem::new_nonterm("expr"),
313316
vec![
@@ -366,14 +369,14 @@ mod test {
366369
let fact_2_num = Rule::from((RuleElem::new_nonterm("fact"), vec![]));
367370

368371
match self {
369-
TestSyntax::ExprPlus => expr_plus,
370-
TestSyntax::ExprMinus => expr_minus,
371-
TestSyntax::Expr2Term => expr_2_term,
372-
TestSyntax::TermMul => term_mul,
373-
TestSyntax::TermDiv => term_div,
374-
TestSyntax::Term2Fact => term_2_fact,
375-
TestSyntax::Fact2Expr => fact_2_expr,
376-
TestSyntax::Fact2Num => fact_2_num,
372+
TestSyntax::ExprPlus => vec![expr_plus],
373+
TestSyntax::ExprMinus => vec![expr_minus],
374+
TestSyntax::Expr2Term => vec![expr_2_term],
375+
TestSyntax::TermMul => vec![term_mul],
376+
TestSyntax::TermDiv => vec![term_div],
377+
TestSyntax::Term2Fact => vec![term_2_fact],
378+
TestSyntax::Fact2Expr => vec![fact_2_expr],
379+
TestSyntax::Fact2Num => vec![fact_2_num],
377380
}
378381
}
379382
}

crates/core_derive/src/impl/syntax.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub fn syntax_proc_macro_impl(ast: DeriveInput) -> TokenStream {
3737
].into_iter()
3838
}
3939

40-
fn into_rule(&self) -> Rule<'a, Self::TokenSet> {
40+
fn into_rules(&self) -> Vec<Rule<'a, Self::TokenSet>> {
4141
match self {
4242
#( #enum_rule_table, )*
4343
_ => unimplemented!(),
@@ -50,23 +50,23 @@ pub fn syntax_proc_macro_impl(ast: DeriveInput) -> TokenStream {
5050
struct VariantInfo<'a> {
5151
parent_ident: &'a Ident,
5252
self_ident: &'a Ident,
53-
rule: Option<TokenStream>,
53+
rules: Vec<TokenStream>,
5454
}
5555

5656
impl<'a> VariantInfo<'a> {
5757
fn parse(parent_ident: &'a Ident, variant: &'a Variant) -> VariantInfo<'a> {
5858
let self_ident = &variant.ident;
5959

60-
let mut rule = None;
60+
let mut rules = vec![];
6161
for attr in &variant.attrs {
6262
let attr = attr.parse_args::<LitStr>().unwrap().value();
63-
rule = Some(Self::parse_rule(&attr));
63+
rules.push(Self::parse_rule(&attr));
6464
}
6565

6666
VariantInfo {
6767
parent_ident,
6868
self_ident,
69-
rule,
69+
rules,
7070
}
7171
}
7272

@@ -102,9 +102,11 @@ impl<'a> VariantInfo<'a> {
102102

103103
fn gen_ident_with_rule(&self) -> TokenStream {
104104
let ident = self.gen_ident();
105-
match &self.rule {
106-
Some(rule) => quote! { #ident => #rule },
107-
None => quote! { unimplemented!() },
105+
if self.rules.is_empty() {
106+
quote! { #ident => unimplemented!() }
107+
} else {
108+
let rules = &self.rules;
109+
quote! { #ident => vec![#(#rules),*] }
108110
}
109111
}
110112
}

examples/expr.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,14 @@ enum ExprTokenSet {
2828
#[derive(Debug, Clone, Copy, Syntax)]
2929
enum ExprSyntax {
3030
#[rule("<expr> ::= <expr> Plus <term>")]
31-
ExprPlus,
3231
#[rule("<expr> ::= <expr> Minus <term>")]
33-
ExprMinus,
3432
#[rule("<expr> ::= <term>")]
35-
ExprTerm,
33+
Expr,
3634
#[rule("<term> ::= <term> Mul <num>")]
37-
TermMul,
3835
#[rule("<term> ::= <term> Div <num>")]
39-
TermDiv,
4036
#[rule("<term> ::= <num>")]
41-
TermNum,
37+
Term,
4238
#[rule("<num> ::= BracketL <expr> BracketR")]
43-
NestedNum,
4439
#[rule("<num> ::= Num")]
4540
Num,
4641
}

tests/derive.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,20 @@ enum TestTokenSet {
2323
#[derive(Debug, Clone, Copy, Syntax)]
2424
enum TestSyntax {
2525
#[rule("<expr> ::= <expr> Plus <term>")]
26-
ExprPlus,
2726
#[rule("<expr> ::= <expr> Minus <term>")]
28-
ExprMinus,
2927
#[rule("<expr> ::= <term>")]
30-
ExprTerm,
28+
Expr,
3129
#[rule("<term> ::= <term> Mul <num>")]
32-
TermMul,
3330
#[rule("<term> ::= <term> Div <num>")]
34-
TermDiv,
3531
#[rule("<term> ::= <num>")]
36-
TermNum,
32+
Term,
3733
#[rule("<num> ::= BracketL <expr> BracketR")]
38-
NestedNum,
3934
#[rule("<num> ::= Num")]
4035
Num,
4136
}
4237

4338
#[test]
4439
fn check_compile() {
4540
let _ = TestTokenSet::into_regex(&self::TestTokenSet::Plus);
46-
let _ = TestSyntax::into_rule(&self::TestSyntax::ExprPlus);
41+
let _ = TestSyntax::into_rules(&self::TestSyntax::Expr);
4742
}

tests/serde.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,14 @@ enum TestTokenSet {
2727
#[derive(Debug, Clone, Copy, Serialize, Deserialize, Syntax)]
2828
enum TestSyntax {
2929
#[rule("<expr> ::= <expr> Plus <term>")]
30-
ExprPlus,
3130
#[rule("<expr> ::= <expr> Minus <term>")]
32-
ExprMinus,
3331
#[rule("<expr> ::= <term>")]
34-
ExprTerm,
32+
Expr,
3533
#[rule("<term> ::= <term> Mul <num>")]
36-
TermMul,
3734
#[rule("<term> ::= <term> Div <num>")]
38-
TermDiv,
3935
#[rule("<term> ::= <num>")]
40-
TermNum,
36+
Term,
4137
#[rule("<num> ::= BracketL <expr> BracketR")]
42-
NestedNum,
4338
#[rule("<num> ::= Num")]
4439
Num,
4540
}

0 commit comments

Comments
 (0)