pomelo_impl/
lib.rs

1#![recursion_limit = "256"]
2extern crate proc_macro;
3extern crate proc_macro2;
4#[macro_use]
5extern crate syn;
6#[macro_use]
7extern crate quote;
8
9mod decl;
10mod parser;
11
12use decl::*;
13
14use syn::parse::{Error, Parse, ParseStream, Result};
15use syn::punctuated::Punctuated;
16use syn::{Attribute, Ident, LitInt, Type, token};
17
18#[doc(hidden)]
19#[proc_macro]
20pub fn pomelo_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
21    let Decls(decls) = parse_macro_input!(input);
22    match pomelo_impl2(decls) {
23        Ok(x) => x,
24        Err(e) => e.to_compile_error().into(),
25    }
26}
27
28fn pomelo_impl2(decls: Vec<Decl>) -> syn::Result<proc_macro::TokenStream> {
29    let mut pomelo = parser::Pomelo::new_from_decls(decls)?;
30    let expanded = pomelo.build()?;
31    let name = pomelo.module_name();
32    let x = quote! {
33        mod #name {
34            #expanded
35        }
36    };
37    Ok(x.into())
38}
39
40struct Decls(Vec<Decl>);
41
42impl Parse for Decls {
43    fn parse(input: ParseStream) -> Result<Decls> {
44        let mut decls = Vec::new();
45        while !input.is_empty() {
46            decls.push(input.parse()?);
47        }
48        Ok(Decls(decls))
49    }
50}
51
52mod kw {
53    custom_keyword!(module);
54    custom_keyword!(include);
55    custom_keyword!(syntax_error);
56    custom_keyword!(parse_fail);
57    custom_keyword!(stack_overflow);
58    custom_keyword!(left);
59    custom_keyword!(right);
60    custom_keyword!(nonassoc);
61    custom_keyword!(default_type);
62    custom_keyword!(extra_argument);
63    custom_keyword!(error);
64    custom_keyword!(start_symbol);
65    custom_keyword!(fallback);
66    custom_keyword!(wildcard);
67    custom_keyword!(token_class);
68    custom_keyword!(token);
69    custom_keyword!(verbose);
70    custom_keyword!(extra_token);
71    custom_keyword!(stack_size);
72    custom_keyword!(parser);
73}
74
75impl Parse for Decl {
76    fn parse(input: ParseStream) -> Result<Decl> {
77        if input.peek(Token![%]) {
78            input.parse::<Token![%]>()?;
79            let lookahead = input.lookahead1();
80            if lookahead.peek(Token![type]) {
81                // %type ident type;
82                input.parse::<Token![type]>()?;
83                let attrs = input.call(Attribute::parse_outer)?;
84                let ident = input.parse::<Ident>()?;
85                let lookahead = input.lookahead1();
86                let typ = if lookahead.peek(Token![;]) {
87                    None
88                } else {
89                    Some(input.parse::<Type>()?)
90                };
91                input.parse::<Token![;]>()?;
92                Ok(Decl::Type(attrs, ident, typ))
93            } else if lookahead.peek(kw::module) {
94                input.parse::<kw::module>()?;
95                // %module ident;
96                let ident = input.parse::<Ident>()?;
97                input.parse::<Token![;]>()?;
98                Ok(Decl::Module(ident))
99            } else if lookahead.peek(kw::include) {
100                // %include { rust-items } [;]
101                input.parse::<kw::include>()?;
102                let code;
103                braced!(code in input);
104                let mut items = Vec::new();
105                while !code.is_empty() {
106                    items.push(code.parse()?);
107                }
108                if input.peek(Token![;]) {
109                    input.parse::<Token![;]>()?;
110                }
111                Ok(Decl::Include(items))
112            } else if lookahead.peek(kw::syntax_error) {
113                // %syntax_error { rust-block }
114                input.parse::<kw::syntax_error>()?;
115                let code = input.parse()?;
116                if input.peek(Token![;]) {
117                    input.parse::<Token![;]>()?;
118                }
119                Ok(Decl::SyntaxError(code))
120            } else if lookahead.peek(kw::parse_fail) {
121                // %parse_fail { rust-block }
122                input.parse::<kw::parse_fail>()?;
123                let code = input.parse()?;
124                if input.peek(Token![;]) {
125                    input.parse::<Token![;]>()?;
126                }
127                Ok(Decl::ParseFail(code))
128            } else if lookahead.peek(kw::stack_overflow) {
129                // %stack_overflow { rust-block }
130                input.parse::<kw::stack_overflow>()?;
131                let code = input.parse()?;
132                if input.peek(Token![;]) {
133                    input.parse::<Token![;]>()?;
134                }
135                Ok(Decl::StackOverflow(code))
136            } else if lookahead.peek(kw::left) {
137                // %left token1 token2 ... ;
138                input.parse::<kw::left>()?;
139                let mut toks = Vec::new();
140                while !input.peek(Token![;]) {
141                    toks.push(input.parse()?);
142                }
143                input.parse::<Token![;]>()?;
144                Ok(Decl::Assoc(Associativity::Left, toks))
145            } else if lookahead.peek(kw::right) {
146                // %right token1 token2 ... ;
147                input.parse::<kw::right>()?;
148                let mut toks = Vec::new();
149                while !input.peek(Token![;]) {
150                    toks.push(input.parse()?);
151                }
152                input.parse::<Token![;]>()?;
153                Ok(Decl::Assoc(Associativity::Right, toks))
154            } else if lookahead.peek(kw::nonassoc) {
155                // %nonassoc token1 token2 ... ;
156                input.parse::<kw::nonassoc>()?;
157                let mut toks = Vec::new();
158                while !input.peek(Token![;]) {
159                    toks.push(input.parse()?);
160                }
161                input.parse::<Token![;]>()?;
162                Ok(Decl::Assoc(Associativity::None, toks))
163            } else if lookahead.peek(kw::default_type) {
164                // %default_type type;
165                input.parse::<kw::default_type>()?;
166                let typ = input.parse()?;
167                input.parse::<Token![;]>()?;
168                Ok(Decl::DefaultType(typ))
169            } else if lookahead.peek(kw::extra_argument) {
170                // %extra_argument type;
171                input.parse::<kw::extra_argument>()?;
172                let typ = input.parse()?;
173                input.parse::<Token![;]>()?;
174                Ok(Decl::ExtraArgument(typ))
175            } else if lookahead.peek(kw::error) {
176                // %error type;
177                input.parse::<kw::error>()?;
178                let typ = input.parse()?;
179                input.parse::<Token![;]>()?;
180                Ok(Decl::Error(typ))
181            } else if lookahead.peek(kw::start_symbol) {
182                // %start_symbol id;
183                input.parse::<kw::start_symbol>()?;
184                let id = input.parse()?;
185                input.parse::<Token![;]>()?;
186                Ok(Decl::StartSymbol(id))
187            } else if lookahead.peek(kw::fallback) {
188                // %fallback id_fall id1 id2 ... ;
189                input.parse::<kw::fallback>()?;
190                let fallback = input.parse()?;
191                let mut ids = Vec::new();
192                while !input.peek(Token![;]) {
193                    ids.push(input.parse()?);
194                }
195                input.parse::<Token![;]>()?;
196                Ok(Decl::Fallback(fallback, ids))
197            } else if lookahead.peek(kw::wildcard) {
198                // %wildcard id;
199                input.parse::<kw::wildcard>()?;
200                let id = input.parse()?;
201                input.parse::<Token![;]>()?;
202                Ok(Decl::Wildcard(id))
203            } else if lookahead.peek(kw::token_class) {
204                // %token_class tk id1 id2... ;
205                input.parse::<kw::token_class>()?;
206                let tk = input.parse()?;
207                let mut ids = Vec::new();
208                while !input.peek(Token![;]) {
209                    ids.push(input.parse()?);
210                }
211                input.parse::<Token![;]>()?;
212                Ok(Decl::TokenClass(tk, ids))
213            } else if lookahead.peek(kw::token) {
214                // %token enum;
215                input.parse::<kw::token>()?;
216                let e = input.parse()?;
217                input.parse::<Token![;]>()?;
218                Ok(Decl::Token(e))
219            } else if lookahead.peek(kw::extra_token) {
220                // %extra_token type;
221                input.parse::<kw::extra_token>()?;
222                let typ = input.parse()?;
223                input.parse::<Token![;]>()?;
224                Ok(Decl::ExtraToken(typ))
225            } else if lookahead.peek(kw::stack_size) {
226                // %stack_size limit [type];
227                input.parse::<kw::stack_size>()?;
228                let limit = input.parse::<LitInt>()?.base10_parse::<usize>()?;
229                let typ = if input.peek(Token![;]) {
230                    None
231                } else {
232                    Some(input.parse()?)
233                };
234                input.parse::<Token![;]>()?;
235                Ok(Decl::StackSize(limit, typ))
236            } else if lookahead.peek(kw::verbose) {
237                // %verbose;
238                input.parse::<kw::verbose>()?;
239                input.parse::<Token![;]>()?;
240                Ok(Decl::Verbose)
241            } else if lookahead.peek(kw::parser) {
242                // %parser struct;
243                input.parse::<kw::parser>()?;
244                let e = input.parse()?;
245                input.parse::<Token![;]>()?;
246                Ok(Decl::Parser(e))
247            } else {
248                Err(lookahead.error())
249            }
250        } else {
251            // rule: id ::= rhs1 rhs2 ... [[precedence]] [ { code } ] [;]
252            // rhs:  id1|id2[?][(alias)]
253            let lhs = input
254                .parse::<Ident>()
255                .map_err(|e| Error::new(e.span(), "% or identifier expected"))?;
256            input.parse::<Token![::]>()?;
257            input.parse::<Token![=]>()?;
258            let mut rhs = Vec::new();
259            loop {
260                let lookahead = input.lookahead1();
261                if !lookahead.peek(Ident) {
262                    break;
263                }
264                //rhs
265                let toks = Punctuated::<Ident, Token![|]>::parse_separated_nonempty(input)?;
266                let toks = toks.into_iter().collect();
267                let optional = if input.peek(Token![?]) {
268                    input.parse::<Token![?]>()?;
269                    true
270                } else {
271                    false
272                };
273                let alias = if input.peek(token::Paren) {
274                    let sub;
275                    parenthesized!(sub in input);
276                    Some(syn::Pat::parse_multi(&sub)?)
277                } else {
278                    None
279                };
280                rhs.push((toks, optional, alias));
281            }
282            let prec = if input.peek(token::Bracket) {
283                let sub;
284                bracketed!(sub in input);
285                Some(sub.parse()?)
286            } else {
287                None
288            };
289            let action = if input.peek(token::Brace) {
290                Some(input.parse()?)
291            } else {
292                None
293            };
294            if input.peek(Token![;]) {
295                input.parse::<Token![;]>()?;
296            }
297            Ok(Decl::Rule {
298                lhs,
299                rhs,
300                action,
301                prec,
302            })
303        }
304    }
305}