1pub mod backend;
3pub mod types;
4
5pub use backend::*;
6pub use types::*;
7
8use crate::parser;
9use proc_macro2::{Span, TokenStream};
10use syn::spanned::Spanned as _;
11use syn::{Attribute, Generics, Ident, ItemUse, Lit, Type};
12
13#[derive(Debug, Clone)]
14pub struct GrammarDefinition {
15 pub name: Ident,
16 pub inherits: Option<Ident>,
17 pub uses: Vec<ItemUse>,
18 pub rules: Vec<Rule>,
19}
20
21#[derive(Debug, Clone)]
22pub struct Rule {
23 pub attrs: Vec<Attribute>,
24 pub is_pub: bool,
25 pub name: Ident,
26 pub generics: Generics,
27 pub params: Vec<(Ident, Option<Type>)>,
28 pub return_type: Type,
29 pub variants: Vec<RuleVariant>,
30}
31
32#[derive(Debug, Clone)]
33pub struct RuleVariant {
34 pub pattern: Vec<ModelPattern>,
35 pub action: TokenStream,
36}
37
38#[derive(Debug, Clone)]
39pub enum ModelPattern {
40 Cut(Span),
41 Lit {
42 binding: Option<Ident>,
43 lit: Lit,
44 },
45 RuleCall {
46 binding: Option<Ident>,
47 rule_name: Ident,
48 args: Vec<ModelPattern>,
49 },
50 Group(Vec<Vec<ModelPattern>>, Span),
51 Bracketed(Vec<ModelPattern>, Span),
52 Braced(Vec<ModelPattern>, Span),
53 Parenthesized(Vec<ModelPattern>, Span),
54 Optional(Box<ModelPattern>, Span),
55 Repeat(Box<ModelPattern>, Span),
56 Plus(Box<ModelPattern>, Span),
57 SpanBinding(Box<ModelPattern>, Ident, Span),
58 Recover {
59 binding: Option<Ident>,
60 body: Box<ModelPattern>,
61 sync: Box<ModelPattern>,
62 span: Span,
63 },
64 Peek(Box<ModelPattern>, Span),
65 Not(Box<ModelPattern>, Span),
66}
67
68impl From<parser::GrammarDefinition> for GrammarDefinition {
69 fn from(p: parser::GrammarDefinition) -> Self {
70 Self {
71 name: p.name,
72 inherits: p.inherits.map(|spec| spec.name),
73 uses: p.uses,
74 rules: p.rules.into_iter().map(Into::into).collect(),
75 }
76 }
77}
78
79impl From<parser::Rule> for Rule {
80 fn from(p: parser::Rule) -> Self {
81 Self {
82 attrs: p.attrs,
83 is_pub: p.is_pub.is_some(),
84 name: p.name,
85 generics: p.generics,
86 params: p
87 .params
88 .into_iter()
89 .map(|param| (param.name, param.ty))
90 .collect(),
91 return_type: p.return_type,
92 variants: p.variants.into_iter().map(Into::into).collect(),
93 }
94 }
95}
96
97impl From<parser::RuleVariant> for RuleVariant {
98 fn from(p: parser::RuleVariant) -> Self {
99 Self {
100 pattern: p.pattern.into_iter().map(Into::into).collect(),
101 action: p.action,
102 }
103 }
104}
105
106impl From<parser::Pattern> for ModelPattern {
107 fn from(p: parser::Pattern) -> Self {
108 use parser::Pattern as P;
109 match p {
110 P::Cut(t) => ModelPattern::Cut(t.span()),
111 P::Lit { binding, lit } => ModelPattern::Lit { binding, lit },
112 P::RuleCall {
113 binding,
114 rule_name,
115 args,
116 } => ModelPattern::RuleCall {
117 binding,
118 rule_name,
119 args: args.into_iter().map(ModelPattern::from).collect(),
120 },
121 P::Group(alts, token) => ModelPattern::Group(
122 alts.into_iter()
123 .map(|seq| seq.into_iter().map(ModelPattern::from).collect())
124 .collect(),
125 token.span.join(),
126 ),
127 P::Bracketed(p, token) => ModelPattern::Bracketed(
128 p.into_iter().map(ModelPattern::from).collect(),
129 token.span.join(),
130 ),
131 P::Braced(p, token) => ModelPattern::Braced(
132 p.into_iter().map(ModelPattern::from).collect(),
133 token.span.join(),
134 ),
135 P::Parenthesized(p, _, token) => ModelPattern::Parenthesized(
136 p.into_iter().map(ModelPattern::from).collect(),
137 token.span.join(),
138 ),
139 P::Optional(p, token) => {
140 ModelPattern::Optional(Box::new(ModelPattern::from(*p)), token.span())
141 }
142 P::Repeat(p, token) => {
143 ModelPattern::Repeat(Box::new(ModelPattern::from(*p)), token.span())
144 }
145 P::Plus(p, token) => ModelPattern::Plus(Box::new(ModelPattern::from(*p)), token.span()),
146 P::SpanBinding(p, ident, token) => {
147 ModelPattern::SpanBinding(Box::new(ModelPattern::from(*p)), ident, token.span)
148 }
149 P::Recover {
150 binding,
151 body,
152 sync,
153 kw_token,
154 } => ModelPattern::Recover {
155 binding,
156 body: Box::new(ModelPattern::from(*body)),
157 sync: Box::new(ModelPattern::from(*sync)),
158 span: kw_token.span(),
159 },
160 P::Peek(p, token) => ModelPattern::Peek(Box::new(ModelPattern::from(*p)), token.span()),
161 P::Not(p, token) => ModelPattern::Not(Box::new(ModelPattern::from(*p)), token.span()),
162 }
163 }
164}
165
166impl ModelPattern {
167 pub fn span(&self) -> Span {
168 match self {
169 ModelPattern::Cut(s) => *s,
170 ModelPattern::Lit { lit, .. } => lit.span(),
171 ModelPattern::RuleCall { rule_name, .. } => rule_name.span(),
172 ModelPattern::Optional(_, s)
173 | ModelPattern::Repeat(_, s)
174 | ModelPattern::Plus(_, s) => *s,
175 ModelPattern::SpanBinding(_, _, s) => *s,
176 ModelPattern::Recover { span, .. } => *span,
177 ModelPattern::Group(_, s) => *s,
178 ModelPattern::Bracketed(_, s)
179 | ModelPattern::Braced(_, s)
180 | ModelPattern::Parenthesized(_, s) => *s,
181 ModelPattern::Peek(_, s) | ModelPattern::Not(_, s) => *s,
182 }
183 }
184}