1#[macro_export]
6macro_rules! rusty_peg {
7 { parser $name:ident<'input>: $base:ty { $($grammar_defn:tt)+ } } => {
8 rusty_peg_parser! {
9 parser $name: $base { $($grammar_defn)* }
10 }
11 };
12
13 { parser $name:ident<'input> { $($grammar_defn:tt)+ } } => {
14 rusty_peg_parser! {
15 parser $name: () { $($grammar_defn)* }
16 }
17 };
18}
19
20#[macro_export]
21#[doc(hidden)]
22macro_rules! rusty_peg_parser {
23 { parser $name:ident: $base:ty { $($grammar_defn:tt)* } } => {
24 rusty_peg_parse_grammar_definition! {
25 rusty_peg_parser_parsed {
26 (arg ($name) ($base))
27 (any)
28 (def)
29 (map)
30 (reg)
31 (fld)
32 }
33 $($grammar_defn)*
34 }
35 }
36}
37
38#[macro_export]
77#[doc(hidden)]
78macro_rules! rusty_peg_parse_grammar_definition {
79 {
81 $m:ident {
82 (arg $($args:tt)*)
83 (any $(($any_nt:ident, $any_ty:ty))*)
84 (def $(($def_nt:ident, $def_ty:ty, $def_tt:tt))*)
85 (map $(($map_nt:ident, $map_ty:ty, $map_tt:tt))*)
86 (reg $(($reg_nt:ident, $reg_ty:ty, $reg_tt:tt))*)
87 (fld $(($fld_nt:ident, $fld_ty:ty, $fld_tt:tt))*)
88 }
89 } => {
90 rusty_peg_parser_parsed! {
91 (arg $($args)*)
92 (any $(($any_nt, $any_ty))*)
93 (def $(($def_nt, $def_ty, $def_tt))*)
94 (map $(($map_nt, $map_ty, $map_tt))*)
95 (reg $(($reg_nt, $reg_ty, $reg_tt))*)
96 (fld $(($fld_nt, $fld_ty, $fld_tt))*)
97 }
98 };
99
100 {
102 $m:ident {
103 (arg $($args:tt)*)
104 (any $(($any_nt:ident, $any_ty:ty))*)
105 (def $(($def_nt:ident, $def_ty:ty, $def_tt:tt))*)
106 (map $(($map_nt:ident, $map_ty:ty, $map_tt:tt))*)
107 (reg $(($reg_nt:ident, $reg_ty:ty, $reg_tt:tt))*)
108 (fld $(($fld_nt:ident, $fld_ty:ty, $fld_tt:tt))*)
109 }
110 $nonterminal:ident: $ty:ty = $defn:tt => $body:expr ;
111 $($remainder:tt)*
112 } => {
113 rusty_peg_parse_grammar_definition! {
114 $m {
115 (arg $($args)*)
116 (any $(($any_nt, $any_ty))* ($nonterminal, $ty))
117 (def $(($def_nt, $def_ty, $def_tt))*)
118 (map $(($map_nt, $map_ty, $map_tt))* ($nonterminal, $ty, ($defn => $body)))
119 (reg $(($reg_nt, $reg_ty, $reg_tt))*)
120 (fld $(($fld_nt, $fld_ty, $fld_tt))*)
121 }
122 $($remainder)*
123 }
124 };
125
126 {
128 $m:ident {
129 (arg $($args:tt)*)
130 (any $(($any_nt:ident, $any_ty:ty))*)
131 (def $(($def_nt:ident, $def_ty:ty, $def_tt:tt))*)
132 (map $(($map_nt:ident, $map_ty:ty, $map_tt:tt))*)
133 (reg $(($reg_nt:ident, $reg_ty:ty, $reg_tt:tt))*)
134 (fld $(($fld_nt:ident, $fld_ty:ty, $fld_tt:tt))*)
135 }
136 $nonterminal:ident: $ty:ty = $defn:tt ;
137 $($remainder:tt)*
138 } => {
139 rusty_peg_parse_grammar_definition! {
140 $m {
141 (arg $($args)*)
142 (any $(($any_nt, $any_ty))* ($nonterminal, $ty))
143 (def $(($def_nt, $def_ty, $def_tt))* ($nonterminal, $ty, ($defn)))
144 (map $(($map_nt, $map_ty, $map_tt))*)
145 (reg $(($reg_nt, $reg_ty, $reg_tt))*)
146 (fld $(($fld_nt, $fld_ty, $fld_tt))*)
147 }
148 $($remainder)*
149 }
150 };
151
152 {
154 $m:ident {
155 (arg $($args:tt)*)
156 (any $(($any_nt:ident, $any_ty:ty))*)
157 (def $(($def_nt:ident, $def_ty:ty, $def_tt:tt))*)
158 (map $(($map_nt:ident, $map_ty:ty, $map_tt:tt))*)
159 (reg $(($reg_nt:ident, $reg_ty:ty, $reg_tt:tt))*)
160 (fld $(($fld_nt:ident, $fld_ty:ty, $fld_tt:tt))*)
161 }
162 $nonterminal:ident: $ty:ty = regex($defn:expr);
163 $($remainder:tt)*
164 } => {
165 rusty_peg_parse_grammar_definition! {
166 $m {
167 (arg $($args)*)
168 (any $(($any_nt, $any_ty))* ($nonterminal, $ty))
169 (def $(($def_nt, $def_ty, $def_tt))*)
170 (map $(($map_nt, $map_ty, $map_tt))*)
171 (reg $(($reg_nt, $reg_ty, $reg_tt))* ($nonterminal, $ty, ($defn, [])))
172 (fld $(($fld_nt, $fld_ty, $fld_tt))*)
173 }
174 $($remainder)*
175 }
176 };
177
178 {
180 $m:ident {
181 (arg $($args:tt)*)
182 (any $(($any_nt:ident, $any_ty:ty))*)
183 (def $(($def_nt:ident, $def_ty:ty, $def_tt:tt))*)
184 (map $(($map_nt:ident, $map_ty:ty, $map_tt:tt))*)
185 (reg $(($reg_nt:ident, $reg_ty:ty, $reg_tt:tt))*)
186 (fld $(($fld_nt:ident, $fld_ty:ty, $fld_tt:tt))*)
187 }
188 $nonterminal:ident: $ty:ty = regex($defn:expr) - [ $($exceptions:expr),* ];
189 $($remainder:tt)*
190 } => {
191 rusty_peg_parse_grammar_definition! {
192 $m {
193 (arg $($args)*)
194 (any $(($any_nt, $any_ty))* ($nonterminal, $ty))
195 (def $(($def_nt, $def_ty, $def_tt))*)
196 (map $(($map_nt, $map_ty, $map_tt))*)
197 (reg $(($reg_nt, $reg_ty, $reg_tt))*
198 ($nonterminal, $ty, ($defn, [$($exceptions),*])))
199 (fld $(($fld_nt, $fld_ty, $fld_tt))*)
200 }
201 $($remainder)*
202 }
203 };
204
205 {
207 $m:ident {
208 (arg $($args:tt)*)
209 (any $(($any_nt:ident, $any_ty:ty))*)
210 (def $(($def_nt:ident, $def_ty:ty, $def_tt:tt))*)
211 (map $(($map_nt:ident, $map_ty:ty, $map_tt:tt))*)
212 (reg $(($reg_nt:ident, $reg_ty:ty, $reg_tt:tt))*)
213 (fld $(($fld_nt:ident, $fld_ty:ty, $fld_tt:tt))*)
214 }
215 $nonterminal:ident: $ty:ty = fold(<$lhs_nm:ident:$lhs_defn:tt>,
216 $($rhs_defn:tt => $rhs_expr:expr),+);
217 $($remainder:tt)*
218 } => {
219 rusty_peg_parse_grammar_definition! {
220 $m {
221 (arg $($args)*)
222 (any $(($any_nt, $any_ty))* ($nonterminal, $ty))
223 (def $(($def_nt, $def_ty, $def_tt))*)
224 (map $(($map_nt, $map_ty, $map_tt))*)
225 (reg $(($reg_nt, $reg_ty, $reg_tt))*)
226 (fld $(($fld_nt, $fld_ty, $fld_tt))*
227 ($nonterminal, $ty,
228 (fold($lhs_nm,$lhs_defn,$(($rhs_defn,$rhs_expr)),+))))
229 }
230 $($remainder)*
231 }
232 };
233}
234
235#[macro_export]
238#[doc(hidden)]
239macro_rules! rusty_peg_parser_parsed {
240 {
241 (arg ($name:ident) ($base:ty))
242 (any $(($any_nt:ident, $any_ty:ty))+)
243 (def $(($def_nt:ident, $def_ty:ty, ($def_tt:tt)))*)
244 (map $(($map_nt:ident, $map_ty:ty, ($map_tt:tt => $map_expr:expr)))*)
245 (reg $(($reg_nt:ident, $reg_ty:ty, ($reg_re:expr, [$($reg_exn:expr),*])))*)
246 (fld $(($fld_nt:ident, $fld_ty:ty, $fld_tt:tt))*)
247 } => {
248 pub struct $name<'input> {
249 marker: $crate::util::PhantomData<&'input()>,
250 pub base: $base,
251 caches: Caches<'input>,
252 regexs: Regexs
253 }
254
255 #[allow(non_snake_case)]
256 struct Caches<'input> {
257 __dummy__: (),
258 $($any_nt: $crate::Cache<'input,$any_ty>),*
259 }
260
261 #[allow(non_snake_case)]
262 struct Regexs {
263 __dummy__: (),
264 $($reg_nt: $crate::util::Rc<$crate::util::RegexNt>),*
265 }
266
267 impl<'input> $name<'input> {
268 pub fn new(base: $base) -> $name<'input> {
269 $name {
270 marker: $crate::util::PhantomData,
271 base: base,
272 caches: Caches { __dummy__: (), $($any_nt: $crate::util::HashMap::new()),* },
273 regexs: Regexs {
274 __dummy__: (),
275 $($reg_nt: $crate::util::Rc::new($crate::util::RegexNt::new(
276 $reg_re,
277 vec![$($reg_exn),*].into_iter()
278 .map(|t: &'static str| t.to_string())
279 .collect()))),*
280 },
281 }
282 }
283 }
284
285 $(rusty_peg_declare_map_nonterminal!{$name, $map_nt, $map_ty, $map_tt, $map_expr})*
286 $(rusty_peg_declare_identity_nonterminal!{$name, $def_nt, $def_ty, $def_tt})*
287 $(rusty_peg_declare_regexp_nonterminal!{$name, $reg_nt, $reg_ty})*
288 $(rusty_peg_declare_fold_nonterminal!{$name, $fld_nt, $fld_ty, $fld_tt})*
289 }
290}
291
292#[macro_export]
293#[doc(hidden)]
294macro_rules! rusty_peg_declare_map_nonterminal {
295 ($grammar:ident, $nonterminal:ident, $ty:ty, $defn:tt, $body:expr) => {
296 #[allow(non_camel_case_types)]
297 #[derive(Copy, Clone, Debug)]
298 pub struct $nonterminal;
299
300 impl<'input> $crate::Symbol<'input,$grammar<'input>> for $nonterminal {
301 type Output = $ty;
302
303 fn pretty_print(&self) -> String {
304 stringify!($nonterminal).to_string()
305 }
306
307 fn parse(&self,
308 grammar: &mut $grammar<'input>,
309 start: $crate::Input<'input>)
310 -> $crate::ParseResult<'input,$ty>
311 {
312 $crate::util::memoize(
313 grammar,
314 |g| &mut g.caches.$nonterminal,
315 start.offset,
316 |g| {
317 let parser = rusty_peg_named_item!($defn);
318 let (end, rusty_peg_named_item_pat!($defn)) =
319 try!($crate::Symbol::parse(&parser, g, start));
320 Ok((end,$body))
321 })
322 }
323 }
324 }
325}
326
327#[macro_export]
328#[doc(hidden)]
329macro_rules! rusty_peg_declare_identity_nonterminal {
330 ($grammar:ident, $nonterminal:ident, $ty:ty, $defn:tt) => {
331 #[allow(non_camel_case_types)]
332 #[derive(Copy, Clone, Debug)]
333 pub struct $nonterminal;
334
335 impl<'input> $crate::Symbol<'input,$grammar<'input>> for $nonterminal {
336 type Output = $ty;
337
338 fn pretty_print(&self) -> String {
339 stringify!($nonterminal).to_string()
340 }
341
342 fn parse(&self,
343 grammar: &mut $grammar<'input>,
344 start: $crate::Input<'input>)
345 -> $crate::ParseResult<'input,$ty>
346 {
347 $crate::util::memoize(
348 grammar,
349 |g| &mut g.caches.$nonterminal,
350 start.offset,
351 |g| {
352 let parser = rusty_peg_item!($defn);
353 $crate::Symbol::parse(&parser, g, start)
354 })
355 }
356 }
357 }
358}
359
360#[macro_export]
361#[doc(hidden)]
362macro_rules! rusty_peg_declare_regexp_nonterminal {
363 ($grammar:ident, $nonterminal:ident, $ty:ty) => {
364 #[allow(non_camel_case_types)]
365 #[derive(Copy, Clone, Debug)]
366 pub struct $nonterminal;
367
368 impl<'input> $crate::Symbol<'input,$grammar<'input>> for $nonterminal {
369 type Output = $ty;
370
371 fn pretty_print(&self) -> String {
372 stringify!($nonterminal).to_string()
373 }
374
375 fn parse(&self,
376 grammar: &mut $grammar<'input>,
377 start: $crate::Input<'input>)
378 -> $crate::ParseResult<'input,$ty>
379 {
380 let regex = grammar.regexs.$nonterminal.clone();
381 $crate::util::memoize(
382 grammar,
383 |grammar| &mut grammar.caches.$nonterminal,
384 start.offset,
385 |grammar| {
386 $crate::Symbol::parse(
387 &*regex,
388 grammar,
389 start)
390 })
391 }
392 }
393 }
394}
395
396#[macro_export]
397#[doc(hidden)]
398macro_rules! rusty_peg_declare_fold_nonterminal {
399 ($grammar:ident, $nonterminal:ident, $ty:ty,
400 (fold($lhs_nm:ident,$lhs_defn:tt,$(($rhs_defn:tt,$rhs_expr:expr)),+))) => {
401 #[allow(non_camel_case_types)]
402 #[derive(Copy, Clone, Debug)]
403 pub struct $nonterminal;
404
405 impl<'input> $crate::Symbol<'input,$grammar<'input>> for $nonterminal {
406 type Output = $ty;
407
408 fn pretty_print(&self) -> String {
409 stringify!($nonterminal).to_string()
410 }
411
412 fn parse(&self,
413 grammar: &mut $grammar<'input>,
414 start: $crate::Input<'input>)
415 -> $crate::ParseResult<'input,$ty>
416 {
417 $crate::util::memoize(
418 grammar,
419 |grammar| &mut grammar.caches.$nonterminal,
420 start.offset,
421 |grammar| {
422 let lhs_parser = rusty_peg_item!($lhs_defn);
423 let (mut mid, mut $lhs_nm) =
424 try!($crate::Symbol::parse(&lhs_parser,
425 grammar,
426 start));
427 loop {
428 mid = $crate::util::skip_whitespace(mid);
429
430 $(
431 let rhs_parser = rusty_peg_named_item!($rhs_defn);
432 match $crate::Symbol::parse(&rhs_parser, grammar, mid) {
433 Ok((end, rusty_peg_named_item_pat!($rhs_defn))) => {
434 $lhs_nm = $rhs_expr;
435 mid = end;
436 continue;
437 }
438 Err(_) => { }
439 }
440 )+
441
442 break;
443 }
444
445 Ok((mid, $lhs_nm))
446 })
447 }
448 }
449 }
450}
451
452#[macro_export]
453#[doc(hidden)]
454macro_rules! rusty_peg_named_item {
455 ( ( $($a:tt)* ) ) => {
456 rusty_peg_named_items!($($a)*)
457 };
458 ( $a:tt ) => {
459 rusty_peg_item!($a)
460 }
461}
462
463#[macro_export]
464#[doc(hidden)]
465macro_rules! rusty_peg_named_items {
466 ( < $name:ident : $a:tt > , $($bs:tt)* ) => {
467 {
468 let bs = rusty_peg_named_items!($($bs)*);
469 rusty_peg_items!($a, bs)
470 }
471 };
472 ( < $name:ident : $a:tt > ) => {
473 rusty_peg_item!($a)
474 };
475 ( $a:tt, $($bs:tt)* ) => {
476 {
477 let bs = rusty_peg_named_items!($($bs)*);
478 rusty_peg_items!($a, bs)
479 }
480 };
481 ( $a:tt ) => {
482 rusty_peg_item!($a)
483 };
484 ( ) => {
485 Empty
486 };
487}
488
489#[macro_export]
490#[doc(hidden)]
491macro_rules! rusty_peg_named_item_pat {
492 ( ( $($a:tt)* ) ) => {
493 rusty_peg_named_items_pat!($($a)*)
494 };
495 ( $a:tt ) => {
496 _
497 }
498}
499
500#[macro_export]
501#[doc(hidden)]
502macro_rules! rusty_peg_named_items_pat {
503 ( < $name:ident : $a:tt > , $($bs:tt)* ) => {
504 ($name, rusty_peg_named_items_pat!($($bs)*))
505 };
506 ( < $name:ident : $a:tt > ) => {
507 $name
508 };
509 ( $a:tt, $($bs:tt)* ) => {
510 (_, rusty_peg_named_items_pat!($($bs)*))
511 };
512 ( $a:tt ) => {
513 _
514 };
515 ( ) => {
516 ()
517 };
518}
519
520#[macro_export]
521#[doc(hidden)]
522macro_rules! rusty_peg_items {
523 ( $a:tt, $($bs:tt)* ) => {
524 $crate::util::Join { first: rusty_peg_item!($a), second: rusty_peg_items!($($bs)*), }
525 };
526 ( $a:tt / $($bs:tt)* ) => {
527 $crate::util::Or { a: rusty_peg_item!($a), b: rusty_peg_items!($($bs)*) }
528 };
529 ( $a:tt ) => {
530 rusty_peg_item!($a)
531 };
532 ( ) => {
533 Empty
534 }
535}
536
537#[macro_export]
538#[doc(hidden)]
539macro_rules! rusty_peg_item {
540 { ( ) } => {
541 Empty
542 };
543
544 { ( $tt:tt ) } => {
545 rusty_peg_item!($tt)
546 };
547
548 { ( $($tt:tt)* ) } => {
549 rusty_peg_items!($($tt)*)
550 };
551
552 { [ $($tt:tt)* ] } => {
553 $crate::util::Optional { parser: rusty_peg_items!($($tt)*) }
554 };
555
556 { { + $($tt:tt)* } } => {
557 $crate::util::Repeat { parser: rusty_peg_items!($($tt)*), min: 1,
558 separator: $crate::util::Whitespace }
559 };
560
561 { { * $($tt:tt)* } } => {
562 $crate::util::Repeat { parser: rusty_peg_items!($($tt)*), min: 0,
563 separator: $crate::util::Whitespace }
564 };
565
566 { { $($tt:tt)* } } => {
567 $crate::util::Repeat { parser: rusty_peg_items!($($tt)*), min: 0,
568 separator: $crate::util::Whitespace }
569 };
570
571 { $name:expr } => {
572 $name
573 };
574}
575