Import peg-macros 0.8.1 upstream upstream/0.8.1
authorDongHun Kwak <dh0128.kwak@samsung.com>
Wed, 22 Mar 2023 07:12:18 +0000 (16:12 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Wed, 22 Mar 2023 07:12:18 +0000 (16:12 +0900)
13 files changed:
.cargo_vcs_info.json [new file with mode: 0644]
Cargo.lock [new file with mode: 0644]
Cargo.toml [new file with mode: 0644]
Cargo.toml.orig [new file with mode: 0644]
LICENSE [new file with mode: 0644]
analysis.rs [new file with mode: 0644]
ast.rs [new file with mode: 0644]
bin.rs [new file with mode: 0644]
grammar.rs [new file with mode: 0644]
grammar.rustpeg [new file with mode: 0644]
lib.rs [new file with mode: 0644]
tokens.rs [new file with mode: 0644]
translate.rs [new file with mode: 0644]

diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
new file mode 100644 (file)
index 0000000..83c3a56
--- /dev/null
@@ -0,0 +1,6 @@
+{
+  "git": {
+    "sha1": "4a99950b26cc9cb7fd483ef0983c20e66f68eb2f"
+  },
+  "path_in_vcs": "peg-macros"
+}
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644 (file)
index 0000000..a9bee0b
--- /dev/null
@@ -0,0 +1,42 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "peg-macros"
+version = "0.8.1"
+dependencies = [
+ "peg-runtime",
+ "proc-macro2",
+ "quote",
+]
+
+[[package]]
+name = "peg-runtime"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fa00462b37ead6d11a82c9d568b26682d78e0477dc02d1966c013af80969739"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7bd7356a8122b6c4a24a82b278680c73357984ca2fc79a0f9fa6dea7dced7c58"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644 (file)
index 0000000..06772dc
--- /dev/null
@@ -0,0 +1,42 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "peg-macros"
+version = "0.8.1"
+authors = ["Kevin Mehall <km@kevinmehall.net>"]
+description = "Procedural macros for rust-peg. To use rust-peg, see the `peg` crate."
+license = "MIT"
+repository = "https://github.com/kevinmehall/rust-peg"
+
+[lib]
+name = "peg_macros"
+path = "lib.rs"
+proc-macro = true
+
+[[bin]]
+name = "rust-peg"
+path = "bin.rs"
+test = false
+bench = false
+
+[dependencies.peg-runtime]
+version = "= 0.8.1"
+
+[dependencies.proc-macro2]
+version = "1.0.24"
+
+[dependencies.quote]
+version = "1.0"
+
+[features]
+trace = []
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
new file mode 100644 (file)
index 0000000..c4a9e9d
--- /dev/null
@@ -0,0 +1,27 @@
+[package]
+name = "peg-macros"
+version = "0.8.1"
+authors = [ "Kevin Mehall <km@kevinmehall.net>" ]
+license = "MIT"
+repository = "https://github.com/kevinmehall/rust-peg"
+description = "Procedural macros for rust-peg. To use rust-peg, see the `peg` crate."
+edition = "2018"
+
+[dependencies]
+quote = "1.0"
+proc-macro2 = "1.0.24"
+peg-runtime = { version = "= 0.8.1", path = "../peg-runtime" }
+
+[features]
+trace = []
+
+[lib]
+proc-macro = true
+name = "peg_macros"
+path = "lib.rs"
+
+[[bin]]
+name = "rust-peg"
+path = "bin.rs"
+test = false
+bench = false
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..d8f7bea
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,25 @@
+Copyright (C) 2013 Kevin Mehall
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/analysis.rs b/analysis.rs
new file mode 100644 (file)
index 0000000..ffdac50
--- /dev/null
@@ -0,0 +1,279 @@
+use proc_macro2::Span;
+use std::collections::HashMap;
+
+use crate::ast::*;
+
+pub struct GrammarAnalysis<'a> {
+    pub rules: HashMap<String, &'a Rule>,
+    pub left_recursion: Vec<LeftRecursionError>,
+    pub loop_nullability: Vec<LoopNullabilityError>,
+}
+
+pub fn check<'a>(grammar: &'a Grammar) -> GrammarAnalysis<'a> {
+    let mut rules = HashMap::new();
+
+    // Pick only the first for duplicate rules (the duplicate is reported when translating the rule)
+    for rule in grammar.iter_rules() {
+        rules.entry(rule.name.to_string()).or_insert(rule);
+    }
+
+    let (rule_nullability, left_recursion) = LeftRecursionVisitor::check(grammar, &rules);
+    let loop_nullability = LoopNullabilityVisitor::check(grammar, &rule_nullability);
+
+    GrammarAnalysis {
+        rules,
+        left_recursion,
+        loop_nullability,
+    }
+}
+
+/// Check for infinite loops in the form of left recursion.
+///
+/// If a PEG expression recurses without first consuming input, it will
+/// recurse until the stack overflows.
+struct LeftRecursionVisitor<'a> {
+    stack: Vec<String>,
+    rules: &'a HashMap<String, &'a Rule>,
+    errors: Vec<LeftRecursionError>,
+}
+
+pub struct LeftRecursionError {
+    pub span: Span,
+    pub path: Vec<String>,
+}
+
+impl LeftRecursionError {
+    pub fn msg(&self) -> String {
+        format!(
+            "left recursive rules create an infinite loop: {}",
+            self.path.join(" -> ")
+        )
+    }
+}
+
+impl<'a> LeftRecursionVisitor<'a> {
+    fn check(grammar: &'a Grammar, rules: &HashMap<String, &'a Rule>) -> (HashMap<String, bool>, Vec<LeftRecursionError>) {
+        let mut visitor = LeftRecursionVisitor {
+            rules,
+            errors: Vec::new(),
+            stack: Vec::new(),
+        };
+
+        let mut rule_nullability: HashMap<String, bool> = HashMap::new();
+
+        for rule in grammar.iter_rules() {
+            let nullable = visitor.walk_rule(rule);
+            debug_assert!(visitor.stack.is_empty());
+            rule_nullability.entry(rule.name.to_string()).or_insert(nullable);
+        }
+
+        (rule_nullability, visitor.errors)
+    }
+
+    fn walk_rule(&mut self, rule: &'a Rule) -> bool {
+        self.stack.push(rule.name.to_string());
+        let res = self.walk_expr(&rule.expr);
+        self.stack.pop().unwrap();
+        res
+    }
+
+    /// Walk the prefix of an expression that can be reached without consuming
+    /// input.
+    ///
+    /// Returns true if the rule is known to match completely without consuming
+    /// any input. This is a conservative heuristic, if unknown, we return false
+    /// to avoid reporting false-positives for left recursion.
+    fn walk_expr(&mut self, this_expr: &SpannedExpr) -> bool {
+        use self::Expr::*;
+        match this_expr.expr {
+            RuleExpr(ref rule_ident, _) => {
+                let name = rule_ident.to_string();
+
+                if let Some(rule) = self.rules.get(&name) {
+                    if let Some(loop_start) = self
+                        .stack
+                        .iter()
+                        .position(|caller_name| caller_name == &name)
+                    {
+                        let mut recursive_loop = self.stack[loop_start..].to_vec();
+                        recursive_loop.push(name.clone());
+                        match rule.cache {
+                            None | Some(Cache::Simple) =>
+                                self.errors.push(LeftRecursionError {
+                                    path: recursive_loop,
+                                    span: rule_ident.span(),
+                                }),
+                            _ => ()
+
+                        }
+                        return false;
+                    }
+                    self.walk_rule(rule)
+                } else {
+                    // Missing rule would have already been reported
+                   false
+                }
+            }
+
+            ActionExpr(ref elems, ..) => {
+                for elem in elems {
+                    if !self.walk_expr(&elem.expr) {
+                        return false;
+                    }
+                }
+
+                true
+            }
+
+            ChoiceExpr(ref choices) => {
+                let mut nullable = false;
+                for expr in choices {
+                    nullable |= self.walk_expr(expr);
+                }
+                nullable
+            }
+
+            OptionalExpr(ref expr) | PosAssertExpr(ref expr) | NegAssertExpr(ref expr) => {
+                self.walk_expr(expr);
+                true
+            }
+
+            Repeat { ref inner, ref bound, .. } => {
+                let inner_nullable = self.walk_expr(inner);
+                inner_nullable | !bound.has_lower_bound()
+            }
+
+            MatchStrExpr(ref expr) | QuietExpr(ref expr) => self.walk_expr(expr),
+
+            PrecedenceExpr { ref levels } => {
+                let mut nullable = false;
+
+                for level in levels {
+                    for operator in &level.operators {
+                        let mut operator_nullable = true;
+                        for element in &operator.elements {
+                            if !self.walk_expr(&element.expr) {
+                                operator_nullable = false;
+                                break;
+                            }
+                        }
+                        nullable |= operator_nullable;
+                    }
+                }
+
+               nullable
+            }
+
+            LiteralExpr(_) | PatternExpr(_) | MethodExpr(_, _) | FailExpr(_) | MarkerExpr(_) => false,
+
+            PositionExpr => true,
+        }
+    }
+}
+
+/// Check for loops whose body can succeed without consuming any input, which
+/// will loop infinitely.
+struct LoopNullabilityVisitor<'a> {
+    rule_nullability: &'a HashMap<String, bool>,
+    errors: Vec<LoopNullabilityError>,
+}
+
+pub struct LoopNullabilityError {
+    pub span: Span,
+}
+
+impl LoopNullabilityError {
+    pub fn msg(&self) -> String {
+        format!("loops infinitely because loop body can match without consuming input")
+    }
+}
+
+
+impl<'a> LoopNullabilityVisitor<'a> {
+    fn check(grammar: &'a Grammar, rule_nullability: &HashMap<String, bool>) -> Vec<LoopNullabilityError> {
+        let mut visitor = LoopNullabilityVisitor {
+            rule_nullability,
+            errors: Vec::new(),
+        };
+
+        for rule in grammar.iter_rules() {
+            visitor.walk_expr(&rule.expr);
+        }
+
+        visitor.errors
+    }
+
+
+    /// Walk an expr and its children analyzing the nullability of loop bodies.
+    ///
+    /// Returns true if the rule is known to match completely without consuming
+    /// any input. This is a conservative heuristic; if unknown, we return false
+    /// to avoid reporting false-positives.
+    ///
+    /// This is very similar to LeftRecursionVisitor::walk_expr, but walks the
+    /// entire expression tree rather than just the nullable prefix, and doesn't
+    /// recurse into calls.
+    fn walk_expr(&mut self, this_expr: &SpannedExpr) -> bool {
+        use self::Expr::*;
+        match this_expr.expr {
+            RuleExpr(ref rule_ident, _) => {
+                let name = rule_ident.to_string();
+                *self.rule_nullability.get(&name).unwrap_or(&false)
+            }
+            
+            ActionExpr(ref elems, ..) => {
+                let mut nullable = true;
+                for elem in elems {
+                    nullable &= self.walk_expr(&elem.expr);
+                }
+                nullable
+            }
+
+            ChoiceExpr(ref choices) => {
+                let mut nullable = false;
+                for expr in choices {
+                    nullable |= self.walk_expr(expr);
+                }
+                nullable
+            }
+
+            OptionalExpr(ref expr) | PosAssertExpr(ref expr) | NegAssertExpr(ref expr) => {
+                self.walk_expr(expr);
+                true
+            }
+
+            Repeat { ref inner, ref bound, ref sep } => {
+                let inner_nullable = self.walk_expr(inner);
+                let sep_nullable = sep.as_ref().map_or(true, |sep| self.walk_expr(sep));
+
+                // The entire purpose of this analysis: report errors if the loop body is nullable
+                if inner_nullable && sep_nullable && !bound.has_upper_bound() {
+                    self.errors.push(LoopNullabilityError { span: this_expr.span });
+                }
+                
+                inner_nullable | !bound.has_lower_bound()
+            }
+
+            MatchStrExpr(ref expr) | QuietExpr(ref expr) => self.walk_expr(expr),
+
+            PrecedenceExpr { ref levels } => {
+                let mut nullable = false;
+
+                for level in levels {
+                    for operator in &level.operators {
+                        let mut operator_nullable = true;
+                        for element in &operator.elements {
+                            operator_nullable &= self.walk_expr(&element.expr);
+                        }
+                        nullable |= operator_nullable;
+                    }
+                }
+
+                nullable 
+            }
+
+            LiteralExpr(_) | PatternExpr(_) | MethodExpr(_, _) | FailExpr(_) | MarkerExpr(_) => false,
+            PositionExpr => true,
+        }
+    }
+}
diff --git a/ast.rs b/ast.rs
new file mode 100644 (file)
index 0000000..24ff565
--- /dev/null
+++ b/ast.rs
@@ -0,0 +1,140 @@
+use proc_macro2::{Group, Ident, Literal, Span, TokenStream};
+
+#[derive(Debug)]
+pub struct Grammar {
+    pub doc: Option<TokenStream>,
+    pub visibility: Option<TokenStream>,
+    pub name: Ident,
+    pub lifetime_params: Option<Vec<TokenStream>>,
+    pub args: Vec<(Ident, TokenStream)>,
+    pub items: Vec<Item>,
+    pub input_type: TokenStream,
+}
+
+impl Grammar {
+    pub fn iter_rules(&self) -> impl Iterator<Item = &Rule> {
+        self.items.iter().filter_map(|item| match item {
+            Item::Rule(r) => Some(r),
+            _ => None,
+        })
+    }
+}
+
+#[derive(Debug)]
+pub enum Item {
+    Use(TokenStream),
+    Rule(Rule),
+}
+
+#[derive(Debug)]
+pub enum Cache {
+    Simple,
+    Recursive
+}
+
+#[derive(Debug)]
+pub struct Rule {
+    pub span: Span,
+    pub name: Ident,
+    pub ty_params: Option<Vec<TokenStream>>,
+    pub params: Vec<RuleParam>,
+    pub expr: SpannedExpr,
+    pub ret_type: Option<TokenStream>,
+    pub doc: Option<TokenStream>,
+    pub visibility: Option<TokenStream>,
+    pub cache: Option<Cache>,
+    pub no_eof: bool,
+}
+
+#[derive(Debug)]
+pub struct RuleParam {
+    pub name: Ident,
+    pub ty: RuleParamTy,
+}
+
+#[derive(Debug)]
+pub enum RuleParamTy {
+    Rust(TokenStream),
+    Rule(TokenStream),
+}
+
+#[derive(Debug, Clone)]
+pub struct TaggedExpr {
+    pub name: Option<Ident>,
+    pub expr: SpannedExpr,
+}
+#[derive(Debug, Clone)]
+pub struct SpannedExpr {
+    pub span: Span,
+    pub expr: Expr,
+}
+
+#[derive(Debug, Clone)]
+pub enum Expr {
+    LiteralExpr(Literal),
+    PatternExpr(Group),
+    RuleExpr(Ident, Vec<RuleArg>),
+    MethodExpr(Ident, TokenStream),
+    ChoiceExpr(Vec<SpannedExpr>),
+    OptionalExpr(Box<SpannedExpr>),
+    Repeat { inner: Box<SpannedExpr>, bound: BoundedRepeat, sep: Option<Box<SpannedExpr>> },
+    PosAssertExpr(Box<SpannedExpr>),
+    NegAssertExpr(Box<SpannedExpr>),
+    ActionExpr(Vec<TaggedExpr>, Option<Group>),
+    MatchStrExpr(Box<SpannedExpr>),
+    PositionExpr,
+    QuietExpr(Box<SpannedExpr>),
+    FailExpr(Literal),
+    PrecedenceExpr {
+        levels: Vec<PrecedenceLevel>,
+    },
+    MarkerExpr(bool),
+}
+
+impl Expr {
+    pub fn at(self, sp: Span) -> SpannedExpr {
+        SpannedExpr { expr: self, span:sp }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub enum RuleArg {
+    Rust(TokenStream),
+    Peg(SpannedExpr),
+}
+
+#[derive(Debug, Clone)]
+pub struct PrecedenceLevel {
+    pub operators: Vec<PrecedenceOperator>,
+}
+
+#[derive(Debug, Clone)]
+pub struct PrecedenceOperator {
+    pub span: Span,
+    pub elements: Vec<TaggedExpr>,
+    pub action: Group,
+}
+
+#[derive(Debug, Clone)]
+pub enum BoundedRepeat {
+    None,
+    Plus,
+    Exact(TokenStream),
+    Both(Option<TokenStream>, Option<TokenStream>),
+}
+
+impl BoundedRepeat {
+    pub fn has_lower_bound(&self) -> bool {
+        match self {
+            BoundedRepeat::None | BoundedRepeat::Both(None, _) => false,
+            BoundedRepeat::Plus | BoundedRepeat::Exact(_) | BoundedRepeat::Both(Some(_), _) => true
+        }
+    }
+
+    pub fn has_upper_bound(&self) -> bool {
+        match self {
+            BoundedRepeat::None |  BoundedRepeat::Plus | BoundedRepeat::Both(_, None) => false,
+            BoundedRepeat::Exact(_) | BoundedRepeat::Both(_, Some(_)) => true
+        }
+    }
+}
diff --git a/bin.rs b/bin.rs
new file mode 100644 (file)
index 0000000..a66f4c5
--- /dev/null
+++ b/bin.rs
@@ -0,0 +1,56 @@
+//! Standalone version of rust-peg used for bootstrapping the meta-grammar
+
+extern crate proc_macro;
+extern crate proc_macro2;
+extern crate quote;
+
+use std::env;
+use std::fs::File;
+use std::io::{stderr, stdin, stdout};
+use std::io::{Read, Write};
+use std::path::Path;
+use std::process;
+
+// This can't use the `peg` crate as it would be a circular dependency, but the generated code in grammar.rs
+// requires `::peg` paths.
+extern crate peg_runtime as peg;
+
+mod analysis;
+mod ast;
+mod grammar;
+mod tokens;
+mod translate;
+
+fn main() {
+    let args = env::args_os().collect::<Vec<_>>();
+    let progname = &args[0];
+    let mut log = stderr();
+
+    let mut source = String::new();
+
+    if args.len() == 2 && &args[1] != "-h" {
+        File::open(Path::new(&args[1]))
+            .unwrap()
+            .read_to_string(&mut source)
+            .unwrap();
+    } else if args.len() == 1 {
+        stdin().read_to_string(&mut source).unwrap();
+    } else {
+        writeln!(log, "Usage: {} [file]", progname.to_string_lossy()).unwrap();
+        process::exit(0);
+    }
+
+    let source_tokens = source.parse().expect("Error tokenizing input");
+    let input_tokens = tokens::FlatTokenStream::new(source_tokens);
+    let grammar = match grammar::peg::peg_grammar(&input_tokens) {
+        Ok(g) => g,
+        Err(err) => {
+            eprintln!("Failed to parse grammar: expected {}", err.expected);
+            process::exit(1);
+        }
+    };
+    let parser_tokens = translate::compile_grammar(&grammar);
+    let mut out = stdout();
+    writeln!(&mut out, "// Generated by rust-peg. Do not edit.").unwrap();
+    write!(&mut out, "{}", parser_tokens).unwrap();
+}
diff --git a/grammar.rs b/grammar.rs
new file mode 100644 (file)
index 0000000..01aba21
--- /dev/null
@@ -0,0 +1,3348 @@
+// Generated by rust-peg. Do not edit.
+pub mod peg {
+    #[allow(unused_imports)]
+    use super::*;
+    type Input = FlatTokenStream;
+    type PositionRepr = <Input as ::peg::Parse>::PositionRepr;
+    #[allow(unused_parens)]
+    struct ParseState<'input> {
+        _phantom: ::std::marker::PhantomData<(&'input ())>,
+        primary_cache: ::std::collections::HashMap<usize, ::peg::RuleResult<SpannedExpr>>,
+    }
+    impl<'input> ParseState<'input> {
+        fn new() -> ParseState<'input> {
+            ParseState {
+                _phantom: ::std::marker::PhantomData,
+                primary_cache: ::std::collections::HashMap::new(),
+            }
+        }
+    }
+    use crate::ast::Expr::*;
+    use crate::ast::*;
+    use crate::tokens::FlatTokenStream;
+    use proc_macro2::{Delimiter, Group, Ident, Literal, Span, TokenStream};
+    pub fn peg_grammar<'input>(
+        __input: &'input Input,
+    ) -> ::std::result::Result<Grammar, ::peg::error::ParseError<PositionRepr>> {
+        #![allow(non_snake_case, unused)]
+        let mut __err_state = ::peg::error::ErrorState::new(::peg::Parse::start(__input));
+        let mut __state = ParseState::new();
+        match __parse_peg_grammar(
+            __input,
+            &mut __state,
+            &mut __err_state,
+            ::peg::Parse::start(__input),
+        ) {
+            ::peg::RuleResult::Matched(__pos, __value) => {
+                if ::peg::Parse::is_eof(__input, __pos) {
+                    return Ok(__value);
+                } else {
+                    __err_state.mark_failure(__pos, "EOF");
+                }
+            }
+            _ => (),
+        }
+        __state = ParseState::new();
+        __err_state.reparse_for_error();
+        match __parse_peg_grammar(
+            __input,
+            &mut __state,
+            &mut __err_state,
+            ::peg::Parse::start(__input),
+        ) {
+            ::peg::RuleResult::<Grammar>::Matched(__pos, __value) => {
+                if ::peg::Parse::is_eof(__input, __pos) {
+                    panic!(
+                        "Parser is nondeterministic: succeeded when reparsing for error position"
+                    );
+                } else {
+                    __err_state.mark_failure(__pos, "EOF");
+                }
+            }
+            _ => (),
+        }
+        Err(__err_state.into_parse_error(__input))
+    }
+    fn __parse_peg_grammar<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<Grammar> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __seq_res = __parse_rust_doc_comment(__input, __state, __err_state, __pos);
+            match __seq_res {
+                ::peg::RuleResult::Matched(__pos, doc) => {
+                    let __seq_res = __parse_rust_visibility(__input, __state, __err_state, __pos);
+                    match __seq_res {
+                        ::peg::RuleResult::Matched(__pos, visibility) => {
+                            match ::peg::ParseLiteral::parse_string_literal(
+                                __input, __pos, "grammar",
+                            ) {
+                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                    let __seq_res =
+                                        __parse_IDENT(__input, __state, __err_state, __pos);
+                                    match __seq_res {
+                                        ::peg::RuleResult::Matched(__pos, name) => {
+                                            let __seq_res = match __parse_rust_lifetime_params(
+                                                __input,
+                                                __state,
+                                                __err_state,
+                                                __pos,
+                                            ) {
+                                                ::peg::RuleResult::Matched(__newpos, __value) => {
+                                                    ::peg::RuleResult::Matched(
+                                                        __newpos,
+                                                        Some(__value),
+                                                    )
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    ::peg::RuleResult::Matched(__pos, None)
+                                                }
+                                            };
+                                            match __seq_res {
+                                                ::peg::RuleResult::Matched(
+                                                    __pos,
+                                                    lifetime_params,
+                                                ) => {
+                                                    let __seq_res = __parse_grammar_args(
+                                                        __input,
+                                                        __state,
+                                                        __err_state,
+                                                        __pos,
+                                                    );
+                                                    match __seq_res { :: peg :: RuleResult :: Matched (__pos , args) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "for") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = { let str_start = __pos ; match match __parse_rust_type (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , :: peg :: ParseSlice :: parse_slice (__input , str_start , __newpos)) } , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , input_type) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "{") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = { let mut __repeat_pos = __pos ; let mut __repeat_value = vec ! () ; loop { let __pos = __repeat_pos ; let __step_res = __parse_item (__input , __state , __err_state , __pos) ; match __step_res { :: peg :: RuleResult :: Matched (__newpos , __value) => { __repeat_pos = __newpos ; __repeat_value . push (__value) ; } , :: peg :: RuleResult :: Failed => { break ; } } } :: peg :: RuleResult :: Matched (__repeat_pos , __repeat_value) } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , items) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "}") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , (|| { Grammar { doc , visibility , name , lifetime_params , args , input_type , items } }) ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"}\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"{\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"for\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    ::peg::RuleResult::Failed
+                                                }
+                                            }
+                                        }
+                                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                    }
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    __err_state.mark_failure(__pos, "\"grammar\"");
+                                    ::peg::RuleResult::Failed
+                                }
+                            }
+                        }
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                    }
+                }
+                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+            }
+        }
+    }
+    fn __parse_rust_lifetime_params<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<Vec<TokenStream>> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "<") {
+            ::peg::RuleResult::Matched(__pos, __val) => {
+                let __seq_res = {
+                    let mut __repeat_pos = __pos;
+                    let mut __repeat_value = vec![];
+                    loop {
+                        let __pos = __repeat_pos;
+                        let __pos = if __repeat_value.is_empty() {
+                            __pos
+                        } else {
+                            let __sep_res = match ::peg::ParseLiteral::parse_string_literal(
+                                __input, __pos, ",",
+                            ) {
+                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                    ::peg::RuleResult::Matched(__pos, __val)
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    __err_state.mark_failure(__pos, "\",\"");
+                                    ::peg::RuleResult::Failed
+                                }
+                            };
+                            match __sep_res {
+                                ::peg::RuleResult::Matched(__newpos, _) => __newpos,
+                                ::peg::RuleResult::Failed => break,
+                            }
+                        };
+                        let __step_res = {
+                            let str_start = __pos;
+                            match match __parse_LIFETIME(__input, __state, __err_state, __pos) {
+                                ::peg::RuleResult::Matched(pos, _) => {
+                                    ::peg::RuleResult::Matched(pos, ())
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                            } {
+                                ::peg::RuleResult::Matched(__newpos, _) => {
+                                    ::peg::RuleResult::Matched(
+                                        __newpos,
+                                        ::peg::ParseSlice::parse_slice(
+                                            __input, str_start, __newpos,
+                                        ),
+                                    )
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                            }
+                        };
+                        match __step_res {
+                            ::peg::RuleResult::Matched(__newpos, __value) => {
+                                __repeat_pos = __newpos;
+                                __repeat_value.push(__value);
+                            }
+                            ::peg::RuleResult::Failed => {
+                                break;
+                            }
+                        }
+                    }
+                    if __repeat_value.len() >= 1 {
+                        ::peg::RuleResult::Matched(__repeat_pos, __repeat_value)
+                    } else {
+                        ::peg::RuleResult::Failed
+                    }
+                };
+                match __seq_res {
+                    ::peg::RuleResult::Matched(__pos, p) => {
+                        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, ">") {
+                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                ::peg::RuleResult::Matched(__pos, (|| p)())
+                            }
+                            ::peg::RuleResult::Failed => {
+                                __err_state.mark_failure(__pos, "\">\"");
+                                ::peg::RuleResult::Failed
+                            }
+                        }
+                    }
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                }
+            }
+            ::peg::RuleResult::Failed => {
+                __err_state.mark_failure(__pos, "\"<\"");
+                ::peg::RuleResult::Failed
+            }
+        }
+    }
+    fn __parse_grammar_args<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<Vec<(Ident, TokenStream)>> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "(") {
+            ::peg::RuleResult::Matched(__pos, __val) => {
+                let __seq_res = {
+                    let mut __repeat_pos = __pos;
+                    let mut __repeat_value = vec![];
+                    loop {
+                        let __pos = __repeat_pos;
+                        let __pos = if __repeat_value.is_empty() {
+                            __pos
+                        } else {
+                            let __sep_res = match ::peg::ParseLiteral::parse_string_literal(
+                                __input, __pos, ",",
+                            ) {
+                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                    ::peg::RuleResult::Matched(__pos, __val)
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    __err_state.mark_failure(__pos, "\",\"");
+                                    ::peg::RuleResult::Failed
+                                }
+                            };
+                            match __sep_res {
+                                ::peg::RuleResult::Matched(__newpos, _) => __newpos,
+                                ::peg::RuleResult::Failed => break,
+                            }
+                        };
+                        let __step_res = {
+                            let __seq_res = __parse_IDENT(__input, __state, __err_state, __pos);
+                            match __seq_res {
+                                ::peg::RuleResult::Matched(__pos, i) => {
+                                    match ::peg::ParseLiteral::parse_string_literal(
+                                        __input, __pos, ":",
+                                    ) {
+                                        ::peg::RuleResult::Matched(__pos, __val) => {
+                                            let __seq_res = {
+                                                let str_start = __pos;
+                                                match match __parse_rust_type(
+                                                    __input,
+                                                    __state,
+                                                    __err_state,
+                                                    __pos,
+                                                ) {
+                                                    ::peg::RuleResult::Matched(pos, _) => {
+                                                        ::peg::RuleResult::Matched(pos, ())
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                } {
+                                                    ::peg::RuleResult::Matched(__newpos, _) => {
+                                                        ::peg::RuleResult::Matched(
+                                                            __newpos,
+                                                            ::peg::ParseSlice::parse_slice(
+                                                                __input, str_start, __newpos,
+                                                            ),
+                                                        )
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                }
+                                            };
+                                            match __seq_res {
+                                                ::peg::RuleResult::Matched(__pos, t) => {
+                                                    ::peg::RuleResult::Matched(__pos, (|| (i, t))())
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    ::peg::RuleResult::Failed
+                                                }
+                                            }
+                                        }
+                                        ::peg::RuleResult::Failed => {
+                                            __err_state.mark_failure(__pos, "\":\"");
+                                            ::peg::RuleResult::Failed
+                                        }
+                                    }
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                            }
+                        };
+                        match __step_res {
+                            ::peg::RuleResult::Matched(__newpos, __value) => {
+                                __repeat_pos = __newpos;
+                                __repeat_value.push(__value);
+                            }
+                            ::peg::RuleResult::Failed => {
+                                break;
+                            }
+                        }
+                    }
+                    ::peg::RuleResult::Matched(__repeat_pos, __repeat_value)
+                };
+                match __seq_res {
+                    ::peg::RuleResult::Matched(__pos, args) => {
+                        let __seq_res = match match ::peg::ParseLiteral::parse_string_literal(
+                            __input, __pos, ",",
+                        ) {
+                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                ::peg::RuleResult::Matched(__pos, __val)
+                            }
+                            ::peg::RuleResult::Failed => {
+                                __err_state.mark_failure(__pos, "\",\"");
+                                ::peg::RuleResult::Failed
+                            }
+                        } {
+                            ::peg::RuleResult::Matched(__newpos, _) => {
+                                ::peg::RuleResult::Matched(__newpos, ())
+                            }
+                            ::peg::RuleResult::Failed => ::peg::RuleResult::Matched(__pos, ()),
+                        };
+                        match __seq_res {
+                            ::peg::RuleResult::Matched(__pos, _) => {
+                                match ::peg::ParseLiteral::parse_string_literal(__input, __pos, ")")
+                                {
+                                    ::peg::RuleResult::Matched(__pos, __val) => {
+                                        ::peg::RuleResult::Matched(__pos, (|| args)())
+                                    }
+                                    ::peg::RuleResult::Failed => {
+                                        __err_state.mark_failure(__pos, "\")\"");
+                                        ::peg::RuleResult::Failed
+                                    }
+                                }
+                            }
+                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                        }
+                    }
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                }
+            }
+            ::peg::RuleResult::Failed => {
+                __err_state.mark_failure(__pos, "\"(\"");
+                ::peg::RuleResult::Failed
+            }
+        }
+    }
+    fn __parse_peg_rule<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<Rule> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __seq_res = __parse_rust_doc_comment(__input, __state, __err_state, __pos);
+            match __seq_res {
+                ::peg::RuleResult::Matched(__pos, doc) => {
+                    let __seq_res = __parse_cacheflag(__input, __state, __err_state, __pos);
+                    match __seq_res {
+                        ::peg::RuleResult::Matched(__pos, cache) => {
+                            let __seq_res =
+                                __parse_no_eof_flag(__input, __state, __err_state, __pos);
+                            match __seq_res {
+                                ::peg::RuleResult::Matched(__pos, no_eof) => {
+                                    let __seq_res = __parse_rust_visibility(
+                                        __input,
+                                        __state,
+                                        __err_state,
+                                        __pos,
+                                    );
+                                    match __seq_res {
+                                        ::peg::RuleResult::Matched(__pos, visibility) => {
+                                            let __seq_res =
+                                                __parse_sp(__input, __state, __err_state, __pos);
+                                            match __seq_res {
+                                                ::peg::RuleResult::Matched(__pos, span) => {
+                                                    match ::peg::ParseLiteral::parse_string_literal(
+                                                        __input, __pos, "rule",
+                                                    ) {
+                                                        ::peg::RuleResult::Matched(
+                                                            __pos,
+                                                            __val,
+                                                        ) => {
+                                                            let __seq_res = {
+                                                                let __choice_res = {
+                                                                    let __seq_res = {
+                                                                        __err_state
+                                                                            .suppress_fail += 1;
+                                                                        let __assert_res = {
+                                                                            let __choice_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "_") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"_\"") ; :: peg :: RuleResult :: Failed } } ;
+                                                                            match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => { let __choice_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "__") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"__\"") ; :: peg :: RuleResult :: Failed } } ; match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "___") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"___\"") ; :: peg :: RuleResult :: Failed } } } } }
+                                                                        };
+                                                                        __err_state
+                                                                            .suppress_fail -= 1;
+                                                                        match __assert_res { :: peg :: RuleResult :: Matched (_ , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                                                    };
+                                                                    match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { { let __seq_res = __parse_IDENT (__input , __state , __err_state , __pos) ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , name) => { { let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "(") { :: peg :: RuleResult :: Matched (__pos , __val) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ")") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\")\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"(\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { :: peg :: RuleResult :: Matched (__pos , (|| { (name , None , Vec :: new ()) }) ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                                                };
+                                                                match __choice_res {
+                                                                    ::peg::RuleResult::Matched(
+                                                                        __pos,
+                                                                        __value,
+                                                                    ) => {
+                                                                        ::peg::RuleResult::Matched(
+                                                                            __pos, __value,
+                                                                        )
+                                                                    }
+                                                                    ::peg::RuleResult::Failed => {
+                                                                        let __seq_res =
+                                                                            __parse_IDENT(
+                                                                                __input,
+                                                                                __state,
+                                                                                __err_state,
+                                                                                __pos,
+                                                                            );
+                                                                        match __seq_res { :: peg :: RuleResult :: Matched (__pos , name) => { { let __seq_res = match __parse_rust_ty_params (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (__newpos , __value) => { :: peg :: RuleResult :: Matched (__newpos , Some (__value)) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , None) } , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , ty_params) => { { let __seq_res = __parse_rule_params (__input , __state , __err_state , __pos) ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , params) => { :: peg :: RuleResult :: Matched (__pos , (|| { (name , ty_params , params) }) ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                                                    }
+                                                                }
+                                                            };
+                                                            match __seq_res {
+                                                                ::peg::RuleResult::Matched(
+                                                                    __pos,
+                                                                    header,
+                                                                ) => {
+                                                                    let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "->") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = { let str_start = __pos ; match match __parse_rust_type (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , :: peg :: ParseSlice :: parse_slice (__input , str_start , __newpos)) } , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , t) => { :: peg :: RuleResult :: Matched (__pos , (|| { t }) ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"->\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , __value) => { :: peg :: RuleResult :: Matched (__newpos , Some (__value)) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , None) } , } ;
+                                                                    match __seq_res { :: peg :: RuleResult :: Matched (__pos , ret_type) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "=") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = __parse_expression (__input , __state , __err_state , __pos) ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , expr) => { { let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ";") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\";\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { :: peg :: RuleResult :: Matched (__pos , (|| { Rule { span , doc , name : header . 0 , ty_params : header . 1 , params : header . 2 , expr , ret_type , visibility , no_eof , cache } }) ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"=\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                                                }
+                                                                ::peg::RuleResult::Failed => {
+                                                                    ::peg::RuleResult::Failed
+                                                                }
+                                                            }
+                                                        }
+                                                        ::peg::RuleResult::Failed => {
+                                                            __err_state
+                                                                .mark_failure(__pos, "\"rule\"");
+                                                            ::peg::RuleResult::Failed
+                                                        }
+                                                    }
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    ::peg::RuleResult::Failed
+                                                }
+                                            }
+                                        }
+                                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                    }
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                            }
+                        }
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                    }
+                }
+                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+            }
+        }
+    }
+    fn __parse_cacheflag<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<Option<Cache>> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __choice_res = match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "#")
+            {
+                ::peg::RuleResult::Matched(__pos, __val) => {
+                    match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "[") {
+                        ::peg::RuleResult::Matched(__pos, __val) => {
+                            match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "cache")
+                            {
+                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                    match ::peg::ParseLiteral::parse_string_literal(
+                                        __input, __pos, "]",
+                                    ) {
+                                        ::peg::RuleResult::Matched(__pos, __val) => {
+                                            ::peg::RuleResult::Matched(
+                                                __pos,
+                                                (|| Some(Cache::Simple))(),
+                                            )
+                                        }
+                                        ::peg::RuleResult::Failed => {
+                                            __err_state.mark_failure(__pos, "\"]\"");
+                                            ::peg::RuleResult::Failed
+                                        }
+                                    }
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    __err_state.mark_failure(__pos, "\"cache\"");
+                                    ::peg::RuleResult::Failed
+                                }
+                            }
+                        }
+                        ::peg::RuleResult::Failed => {
+                            __err_state.mark_failure(__pos, "\"[\"");
+                            ::peg::RuleResult::Failed
+                        }
+                    }
+                }
+                ::peg::RuleResult::Failed => {
+                    __err_state.mark_failure(__pos, "\"#\"");
+                    ::peg::RuleResult::Failed
+                }
+            };
+            match __choice_res {
+                ::peg::RuleResult::Matched(__pos, __value) => {
+                    ::peg::RuleResult::Matched(__pos, __value)
+                }
+                ::peg::RuleResult::Failed => {
+                    let __choice_res =
+                        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "#") {
+                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "[")
+                                {
+                                    ::peg::RuleResult::Matched(__pos, __val) => {
+                                        match ::peg::ParseLiteral::parse_string_literal(
+                                            __input,
+                                            __pos,
+                                            "cache_left_rec",
+                                        ) {
+                                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                                match ::peg::ParseLiteral::parse_string_literal(
+                                                    __input, __pos, "]",
+                                                ) {
+                                                    ::peg::RuleResult::Matched(__pos, __val) => {
+                                                        ::peg::RuleResult::Matched(
+                                                            __pos,
+                                                            (|| Some(Cache::Recursive))(),
+                                                        )
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        __err_state.mark_failure(__pos, "\"]\"");
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                }
+                                            }
+                                            ::peg::RuleResult::Failed => {
+                                                __err_state
+                                                    .mark_failure(__pos, "\"cache_left_rec\"");
+                                                ::peg::RuleResult::Failed
+                                            }
+                                        }
+                                    }
+                                    ::peg::RuleResult::Failed => {
+                                        __err_state.mark_failure(__pos, "\"[\"");
+                                        ::peg::RuleResult::Failed
+                                    }
+                                }
+                            }
+                            ::peg::RuleResult::Failed => {
+                                __err_state.mark_failure(__pos, "\"#\"");
+                                ::peg::RuleResult::Failed
+                            }
+                        };
+                    match __choice_res {
+                        ::peg::RuleResult::Matched(__pos, __value) => {
+                            ::peg::RuleResult::Matched(__pos, __value)
+                        }
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Matched(__pos, (|| None)()),
+                    }
+                }
+            }
+        }
+    }
+    fn __parse_no_eof_flag<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<bool> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __choice_res = match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "#")
+            {
+                ::peg::RuleResult::Matched(__pos, __val) => {
+                    match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "[") {
+                        ::peg::RuleResult::Matched(__pos, __val) => {
+                            match ::peg::ParseLiteral::parse_string_literal(
+                                __input, __pos, "no_eof",
+                            ) {
+                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                    match ::peg::ParseLiteral::parse_string_literal(
+                                        __input, __pos, "]",
+                                    ) {
+                                        ::peg::RuleResult::Matched(__pos, __val) => {
+                                            ::peg::RuleResult::Matched(__pos, (|| true)())
+                                        }
+                                        ::peg::RuleResult::Failed => {
+                                            __err_state.mark_failure(__pos, "\"]\"");
+                                            ::peg::RuleResult::Failed
+                                        }
+                                    }
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    __err_state.mark_failure(__pos, "\"no_eof\"");
+                                    ::peg::RuleResult::Failed
+                                }
+                            }
+                        }
+                        ::peg::RuleResult::Failed => {
+                            __err_state.mark_failure(__pos, "\"[\"");
+                            ::peg::RuleResult::Failed
+                        }
+                    }
+                }
+                ::peg::RuleResult::Failed => {
+                    __err_state.mark_failure(__pos, "\"#\"");
+                    ::peg::RuleResult::Failed
+                }
+            };
+            match __choice_res {
+                ::peg::RuleResult::Matched(__pos, __value) => {
+                    ::peg::RuleResult::Matched(__pos, __value)
+                }
+                ::peg::RuleResult::Failed => ::peg::RuleResult::Matched(__pos, (|| false)()),
+            }
+        }
+    }
+    fn __parse_rule_param_ty<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<RuleParamTy> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __choice_res =
+                match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "rule") {
+                    ::peg::RuleResult::Matched(__pos, __val) => {
+                        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "<") {
+                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                let __seq_res = {
+                                    let str_start = __pos;
+                                    match match __parse_rust_type(
+                                        __input,
+                                        __state,
+                                        __err_state,
+                                        __pos,
+                                    ) {
+                                        ::peg::RuleResult::Matched(pos, _) => {
+                                            ::peg::RuleResult::Matched(pos, ())
+                                        }
+                                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                    } {
+                                        ::peg::RuleResult::Matched(__newpos, _) => {
+                                            ::peg::RuleResult::Matched(
+                                                __newpos,
+                                                ::peg::ParseSlice::parse_slice(
+                                                    __input, str_start, __newpos,
+                                                ),
+                                            )
+                                        }
+                                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                    }
+                                };
+                                match __seq_res {
+                                    ::peg::RuleResult::Matched(__pos, r) => {
+                                        match ::peg::ParseLiteral::parse_string_literal(
+                                            __input, __pos, ">",
+                                        ) {
+                                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                                ::peg::RuleResult::Matched(
+                                                    __pos,
+                                                    (|| RuleParamTy::Rule(r))(),
+                                                )
+                                            }
+                                            ::peg::RuleResult::Failed => {
+                                                __err_state.mark_failure(__pos, "\">\"");
+                                                ::peg::RuleResult::Failed
+                                            }
+                                        }
+                                    }
+                                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                }
+                            }
+                            ::peg::RuleResult::Failed => {
+                                __err_state.mark_failure(__pos, "\"<\"");
+                                ::peg::RuleResult::Failed
+                            }
+                        }
+                    }
+                    ::peg::RuleResult::Failed => {
+                        __err_state.mark_failure(__pos, "\"rule\"");
+                        ::peg::RuleResult::Failed
+                    }
+                };
+            match __choice_res {
+                ::peg::RuleResult::Matched(__pos, __value) => {
+                    ::peg::RuleResult::Matched(__pos, __value)
+                }
+                ::peg::RuleResult::Failed => {
+                    let __seq_res = {
+                        let str_start = __pos;
+                        match match __parse_rust_type(__input, __state, __err_state, __pos) {
+                            ::peg::RuleResult::Matched(pos, _) => {
+                                ::peg::RuleResult::Matched(pos, ())
+                            }
+                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                        } {
+                            ::peg::RuleResult::Matched(__newpos, _) => ::peg::RuleResult::Matched(
+                                __newpos,
+                                ::peg::ParseSlice::parse_slice(__input, str_start, __newpos),
+                            ),
+                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                        }
+                    };
+                    match __seq_res {
+                        ::peg::RuleResult::Matched(__pos, t) => {
+                            ::peg::RuleResult::Matched(__pos, (|| RuleParamTy::Rust(t))())
+                        }
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                    }
+                }
+            }
+        }
+    }
+    fn __parse_rule_params<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<Vec<RuleParam>> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "(") {
+            ::peg::RuleResult::Matched(__pos, __val) => {
+                let __seq_res = {
+                    let mut __repeat_pos = __pos;
+                    let mut __repeat_value = vec![];
+                    loop {
+                        let __pos = __repeat_pos;
+                        let __pos = if __repeat_value.is_empty() {
+                            __pos
+                        } else {
+                            let __sep_res = match ::peg::ParseLiteral::parse_string_literal(
+                                __input, __pos, ",",
+                            ) {
+                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                    ::peg::RuleResult::Matched(__pos, __val)
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    __err_state.mark_failure(__pos, "\",\"");
+                                    ::peg::RuleResult::Failed
+                                }
+                            };
+                            match __sep_res {
+                                ::peg::RuleResult::Matched(__newpos, _) => __newpos,
+                                ::peg::RuleResult::Failed => break,
+                            }
+                        };
+                        let __step_res = {
+                            let __seq_res = __parse_IDENT(__input, __state, __err_state, __pos);
+                            match __seq_res {
+                                ::peg::RuleResult::Matched(__pos, name) => {
+                                    match ::peg::ParseLiteral::parse_string_literal(
+                                        __input, __pos, ":",
+                                    ) {
+                                        ::peg::RuleResult::Matched(__pos, __val) => {
+                                            let __seq_res = __parse_rule_param_ty(
+                                                __input,
+                                                __state,
+                                                __err_state,
+                                                __pos,
+                                            );
+                                            match __seq_res {
+                                                ::peg::RuleResult::Matched(__pos, ty) => {
+                                                    ::peg::RuleResult::Matched(
+                                                        __pos,
+                                                        (|| RuleParam { name, ty })(),
+                                                    )
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    ::peg::RuleResult::Failed
+                                                }
+                                            }
+                                        }
+                                        ::peg::RuleResult::Failed => {
+                                            __err_state.mark_failure(__pos, "\":\"");
+                                            ::peg::RuleResult::Failed
+                                        }
+                                    }
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                            }
+                        };
+                        match __step_res {
+                            ::peg::RuleResult::Matched(__newpos, __value) => {
+                                __repeat_pos = __newpos;
+                                __repeat_value.push(__value);
+                            }
+                            ::peg::RuleResult::Failed => {
+                                break;
+                            }
+                        }
+                    }
+                    ::peg::RuleResult::Matched(__repeat_pos, __repeat_value)
+                };
+                match __seq_res {
+                    ::peg::RuleResult::Matched(__pos, params) => {
+                        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, ")") {
+                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                ::peg::RuleResult::Matched(__pos, (|| params)())
+                            }
+                            ::peg::RuleResult::Failed => {
+                                __err_state.mark_failure(__pos, "\")\"");
+                                ::peg::RuleResult::Failed
+                            }
+                        }
+                    }
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                }
+            }
+            ::peg::RuleResult::Failed => {
+                __err_state.mark_failure(__pos, "\"(\"");
+                ::peg::RuleResult::Failed
+            }
+        }
+    }
+    fn __parse_item<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<Item> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __choice_res = {
+                let __seq_res = __parse_rust_use(__input, __state, __err_state, __pos);
+                match __seq_res {
+                    ::peg::RuleResult::Matched(__pos, u) => {
+                        ::peg::RuleResult::Matched(__pos, (|| Item::Use(u))())
+                    }
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                }
+            };
+            match __choice_res {
+                ::peg::RuleResult::Matched(__pos, __value) => {
+                    ::peg::RuleResult::Matched(__pos, __value)
+                }
+                ::peg::RuleResult::Failed => {
+                    let __seq_res = __parse_peg_rule(__input, __state, __err_state, __pos);
+                    match __seq_res {
+                        ::peg::RuleResult::Matched(__pos, r) => {
+                            ::peg::RuleResult::Matched(__pos, (|| Item::Rule(r))())
+                        }
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                    }
+                }
+            }
+        }
+    }
+    fn __parse_rust_doc_comment<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<Option<TokenStream>> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        match {
+            let str_start = __pos;
+            match {
+                let mut __repeat_pos = __pos;
+                loop {
+                    let __pos = __repeat_pos;
+                    let __step_res = match ::peg::ParseLiteral::parse_string_literal(
+                        __input, __pos, "#",
+                    ) {
+                        ::peg::RuleResult::Matched(__pos, __val) => {
+                            match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "[") {
+                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                    match ::peg::ParseLiteral::parse_string_literal(
+                                        __input, __pos, "doc",
+                                    ) {
+                                        ::peg::RuleResult::Matched(__pos, __val) => {
+                                            match ::peg::ParseLiteral::parse_string_literal(
+                                                __input, __pos, "=",
+                                            ) {
+                                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                                    let __seq_res = match __parse_LITERAL(
+                                                        __input,
+                                                        __state,
+                                                        __err_state,
+                                                        __pos,
+                                                    ) {
+                                                        ::peg::RuleResult::Matched(pos, _) => {
+                                                            ::peg::RuleResult::Matched(pos, ())
+                                                        }
+                                                        ::peg::RuleResult::Failed => {
+                                                            ::peg::RuleResult::Failed
+                                                        }
+                                                    };
+                                                    match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "]") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"]\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    __err_state.mark_failure(__pos, "\"=\"");
+                                                    ::peg::RuleResult::Failed
+                                                }
+                                            }
+                                        }
+                                        ::peg::RuleResult::Failed => {
+                                            __err_state.mark_failure(__pos, "\"doc\"");
+                                            ::peg::RuleResult::Failed
+                                        }
+                                    }
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    __err_state.mark_failure(__pos, "\"[\"");
+                                    ::peg::RuleResult::Failed
+                                }
+                            }
+                        }
+                        ::peg::RuleResult::Failed => {
+                            __err_state.mark_failure(__pos, "\"#\"");
+                            ::peg::RuleResult::Failed
+                        }
+                    };
+                    match __step_res {
+                        ::peg::RuleResult::Matched(__newpos, __value) => {
+                            __repeat_pos = __newpos;
+                        }
+                        ::peg::RuleResult::Failed => {
+                            break;
+                        }
+                    }
+                }
+                ::peg::RuleResult::Matched(__repeat_pos, ())
+            } {
+                ::peg::RuleResult::Matched(__newpos, _) => ::peg::RuleResult::Matched(
+                    __newpos,
+                    ::peg::ParseSlice::parse_slice(__input, str_start, __newpos),
+                ),
+                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+            }
+        } {
+            ::peg::RuleResult::Matched(__newpos, __value) => {
+                ::peg::RuleResult::Matched(__newpos, Some(__value))
+            }
+            ::peg::RuleResult::Failed => ::peg::RuleResult::Matched(__pos, None),
+        }
+    }
+    fn __parse_rust_visibility<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<Option<TokenStream>> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        match {
+            let str_start = __pos;
+            match {
+                let __choice_res =
+                    match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "pub") {
+                        ::peg::RuleResult::Matched(__pos, __val) => {
+                            let __seq_res = match match __parse_PAREN_GROUP(
+                                __input,
+                                __state,
+                                __err_state,
+                                __pos,
+                            ) {
+                                ::peg::RuleResult::Matched(pos, _) => {
+                                    ::peg::RuleResult::Matched(pos, ())
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                            } {
+                                ::peg::RuleResult::Matched(__newpos, _) => {
+                                    ::peg::RuleResult::Matched(__newpos, ())
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Matched(__pos, ()),
+                            };
+                            match __seq_res {
+                                ::peg::RuleResult::Matched(__pos, _) => {
+                                    ::peg::RuleResult::Matched(__pos, ())
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                            }
+                        }
+                        ::peg::RuleResult::Failed => {
+                            __err_state.mark_failure(__pos, "\"pub\"");
+                            ::peg::RuleResult::Failed
+                        }
+                    };
+                match __choice_res {
+                    ::peg::RuleResult::Matched(__pos, __value) => {
+                        ::peg::RuleResult::Matched(__pos, __value)
+                    }
+                    ::peg::RuleResult::Failed => {
+                        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "crate") {
+                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                ::peg::RuleResult::Matched(__pos, __val)
+                            }
+                            ::peg::RuleResult::Failed => {
+                                __err_state.mark_failure(__pos, "\"crate\"");
+                                ::peg::RuleResult::Failed
+                            }
+                        }
+                    }
+                }
+            } {
+                ::peg::RuleResult::Matched(__newpos, _) => ::peg::RuleResult::Matched(
+                    __newpos,
+                    ::peg::ParseSlice::parse_slice(__input, str_start, __newpos),
+                ),
+                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+            }
+        } {
+            ::peg::RuleResult::Matched(__newpos, __value) => {
+                ::peg::RuleResult::Matched(__newpos, Some(__value))
+            }
+            ::peg::RuleResult::Failed => ::peg::RuleResult::Matched(__pos, None),
+        }
+    }
+    fn __parse_rust_use<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<TokenStream> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __seq_res = {
+                let str_start = __pos;
+                match match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "use") {
+                    ::peg::RuleResult::Matched(__pos, __val) => {
+                        let __seq_res =
+                            match __parse_rust_path(__input, __state, __err_state, __pos) {
+                                ::peg::RuleResult::Matched(pos, _) => {
+                                    ::peg::RuleResult::Matched(pos, ())
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                            };
+                        match __seq_res {
+                            ::peg::RuleResult::Matched(__pos, _) => {
+                                let __seq_res = {
+                                    let __choice_res =
+                                        match ::peg::ParseLiteral::parse_string_literal(
+                                            __input, __pos, "::",
+                                        ) {
+                                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                                match ::peg::ParseLiteral::parse_string_literal(
+                                                    __input, __pos, "*",
+                                                ) {
+                                                    ::peg::RuleResult::Matched(__pos, __val) => {
+                                                        ::peg::RuleResult::Matched(__pos, ())
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        __err_state.mark_failure(__pos, "\"*\"");
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                }
+                                            }
+                                            ::peg::RuleResult::Failed => {
+                                                __err_state.mark_failure(__pos, "\"::\"");
+                                                ::peg::RuleResult::Failed
+                                            }
+                                        };
+                                    match __choice_res {
+                                        ::peg::RuleResult::Matched(__pos, __value) => {
+                                            ::peg::RuleResult::Matched(__pos, __value)
+                                        }
+                                        ::peg::RuleResult::Failed => {
+                                            let __choice_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "::") { :: peg :: RuleResult :: Matched (__pos , __val) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "{") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = { let mut __repeat_pos = __pos ; let mut __repeat_value = vec ! () ; loop { let __pos = __repeat_pos ; let __pos = if __repeat_value . is_empty () { __pos } else { let __sep_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ",") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\",\"") ; :: peg :: RuleResult :: Failed } } ; match __sep_res { :: peg :: RuleResult :: Matched (__newpos , _) => { __newpos } , :: peg :: RuleResult :: Failed => break , } } ; let __step_res = { let __seq_res = match __parse_IDENT (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { { let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "as") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = match __parse_IDENT (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"as\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } ; match __step_res { :: peg :: RuleResult :: Matched (__newpos , __value) => { __repeat_pos = __newpos ; __repeat_value . push (__value) ; } , :: peg :: RuleResult :: Failed => { break ; } } } if __repeat_value . len () >= 1 { :: peg :: RuleResult :: Matched (__repeat_pos , ()) } else { :: peg :: RuleResult :: Failed } } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "}") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"}\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"{\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"::\"") ; :: peg :: RuleResult :: Failed } } ;
+                                            match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "as") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = match __parse_IDENT (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"as\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } }
+                                        }
+                                    }
+                                };
+                                match __seq_res {
+                                    ::peg::RuleResult::Matched(__pos, _) => {
+                                        match ::peg::ParseLiteral::parse_string_literal(
+                                            __input, __pos, ";",
+                                        ) {
+                                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                                ::peg::RuleResult::Matched(__pos, ())
+                                            }
+                                            ::peg::RuleResult::Failed => {
+                                                __err_state.mark_failure(__pos, "\";\"");
+                                                ::peg::RuleResult::Failed
+                                            }
+                                        }
+                                    }
+                                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                }
+                            }
+                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                        }
+                    }
+                    ::peg::RuleResult::Failed => {
+                        __err_state.mark_failure(__pos, "\"use\"");
+                        ::peg::RuleResult::Failed
+                    }
+                } {
+                    ::peg::RuleResult::Matched(__newpos, _) => ::peg::RuleResult::Matched(
+                        __newpos,
+                        ::peg::ParseSlice::parse_slice(__input, str_start, __newpos),
+                    ),
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                }
+            };
+            match __seq_res {
+                ::peg::RuleResult::Matched(__pos, v) => {
+                    ::peg::RuleResult::Matched(__pos, (|| v.to_owned())())
+                }
+                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+            }
+        }
+    }
+    fn __parse_rust_path<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<()> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __seq_res =
+                match match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "crate") {
+                    ::peg::RuleResult::Matched(__pos, __val) => {
+                        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "::") {
+                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                ::peg::RuleResult::Matched(__pos, ())
+                            }
+                            ::peg::RuleResult::Failed => {
+                                __err_state.mark_failure(__pos, "\"::\"");
+                                ::peg::RuleResult::Failed
+                            }
+                        }
+                    }
+                    ::peg::RuleResult::Failed => {
+                        __err_state.mark_failure(__pos, "\"crate\"");
+                        ::peg::RuleResult::Failed
+                    }
+                } {
+                    ::peg::RuleResult::Matched(__newpos, _) => {
+                        ::peg::RuleResult::Matched(__newpos, ())
+                    }
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Matched(__pos, ()),
+                };
+            match __seq_res {
+                ::peg::RuleResult::Matched(__pos, _) => {
+                    let __seq_res = {
+                        let mut __repeat_pos = __pos;
+                        let mut __repeat_value = vec![];
+                        loop {
+                            let __pos = __repeat_pos;
+                            let __pos = if __repeat_value.is_empty() {
+                                __pos
+                            } else {
+                                let __sep_res = match ::peg::ParseLiteral::parse_string_literal(
+                                    __input, __pos, "::",
+                                ) {
+                                    ::peg::RuleResult::Matched(__pos, __val) => {
+                                        ::peg::RuleResult::Matched(__pos, __val)
+                                    }
+                                    ::peg::RuleResult::Failed => {
+                                        __err_state.mark_failure(__pos, "\"::\"");
+                                        ::peg::RuleResult::Failed
+                                    }
+                                };
+                                match __sep_res {
+                                    ::peg::RuleResult::Matched(__newpos, _) => __newpos,
+                                    ::peg::RuleResult::Failed => break,
+                                }
+                            };
+                            let __step_res =
+                                match __parse_IDENT(__input, __state, __err_state, __pos) {
+                                    ::peg::RuleResult::Matched(pos, _) => {
+                                        ::peg::RuleResult::Matched(pos, ())
+                                    }
+                                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                };
+                            match __step_res {
+                                ::peg::RuleResult::Matched(__newpos, __value) => {
+                                    __repeat_pos = __newpos;
+                                    __repeat_value.push(__value);
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    break;
+                                }
+                            }
+                        }
+                        if __repeat_value.len() >= 1 {
+                            ::peg::RuleResult::Matched(__repeat_pos, ())
+                        } else {
+                            ::peg::RuleResult::Failed
+                        }
+                    };
+                    match __seq_res {
+                        ::peg::RuleResult::Matched(__pos, _) => {
+                            ::peg::RuleResult::Matched(__pos, ())
+                        }
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                    }
+                }
+                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+            }
+        }
+    }
+    fn __parse_rust_type<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<()> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __choice_res = match __parse_BRACKET_GROUP(__input, __state, __err_state, __pos) {
+                ::peg::RuleResult::Matched(pos, _) => ::peg::RuleResult::Matched(pos, ()),
+                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+            };
+            match __choice_res {
+                ::peg::RuleResult::Matched(__pos, __value) => {
+                    ::peg::RuleResult::Matched(__pos, __value)
+                }
+                ::peg::RuleResult::Failed => {
+                    let __choice_res =
+                        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "&") {
+                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                let __seq_res = match match __parse_LIFETIME(
+                                    __input,
+                                    __state,
+                                    __err_state,
+                                    __pos,
+                                ) {
+                                    ::peg::RuleResult::Matched(pos, _) => {
+                                        ::peg::RuleResult::Matched(pos, ())
+                                    }
+                                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                } {
+                                    ::peg::RuleResult::Matched(__newpos, _) => {
+                                        ::peg::RuleResult::Matched(__newpos, ())
+                                    }
+                                    ::peg::RuleResult::Failed => {
+                                        ::peg::RuleResult::Matched(__pos, ())
+                                    }
+                                };
+                                match __seq_res {
+                                    ::peg::RuleResult::Matched(__pos, _) => {
+                                        let __seq_res =
+                                            match match ::peg::ParseLiteral::parse_string_literal(
+                                                __input, __pos, "mut",
+                                            ) {
+                                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                                    ::peg::RuleResult::Matched(__pos, __val)
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    __err_state.mark_failure(__pos, "\"mut\"");
+                                                    ::peg::RuleResult::Failed
+                                                }
+                                            } {
+                                                ::peg::RuleResult::Matched(__newpos, _) => {
+                                                    ::peg::RuleResult::Matched(__newpos, ())
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    ::peg::RuleResult::Matched(__pos, ())
+                                                }
+                                            };
+                                        match __seq_res {
+                                            ::peg::RuleResult::Matched(__pos, _) => {
+                                                let __seq_res = match __parse_rust_type(
+                                                    __input,
+                                                    __state,
+                                                    __err_state,
+                                                    __pos,
+                                                ) {
+                                                    ::peg::RuleResult::Matched(pos, _) => {
+                                                        ::peg::RuleResult::Matched(pos, ())
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                };
+                                                match __seq_res {
+                                                    ::peg::RuleResult::Matched(__pos, _) => {
+                                                        ::peg::RuleResult::Matched(__pos, ())
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                }
+                                            }
+                                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                        }
+                                    }
+                                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                }
+                            }
+                            ::peg::RuleResult::Failed => {
+                                __err_state.mark_failure(__pos, "\"&\"");
+                                ::peg::RuleResult::Failed
+                            }
+                        };
+                    match __choice_res {
+                        ::peg::RuleResult::Matched(__pos, __value) => {
+                            ::peg::RuleResult::Matched(__pos, __value)
+                        }
+                        ::peg::RuleResult::Failed => {
+                            let __choice_res = match ::peg::ParseLiteral::parse_string_literal(
+                                __input, __pos, "dyn",
+                            ) {
+                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                    let __seq_res = match __parse_rust_type(
+                                        __input,
+                                        __state,
+                                        __err_state,
+                                        __pos,
+                                    ) {
+                                        ::peg::RuleResult::Matched(pos, _) => {
+                                            ::peg::RuleResult::Matched(pos, ())
+                                        }
+                                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                    };
+                                    match __seq_res {
+                                        ::peg::RuleResult::Matched(__pos, _) => {
+                                            ::peg::RuleResult::Matched(__pos, ())
+                                        }
+                                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                    }
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    __err_state.mark_failure(__pos, "\"dyn\"");
+                                    ::peg::RuleResult::Failed
+                                }
+                            };
+                            match __choice_res {
+                                ::peg::RuleResult::Matched(__pos, __value) => {
+                                    ::peg::RuleResult::Matched(__pos, __value)
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    let __choice_res =
+                                        match ::peg::ParseLiteral::parse_string_literal(
+                                            __input, __pos, "impl",
+                                        ) {
+                                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                                let __seq_res = match __parse_rust_type(
+                                                    __input,
+                                                    __state,
+                                                    __err_state,
+                                                    __pos,
+                                                ) {
+                                                    ::peg::RuleResult::Matched(pos, _) => {
+                                                        ::peg::RuleResult::Matched(pos, ())
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                };
+                                                match __seq_res {
+                                                    ::peg::RuleResult::Matched(__pos, _) => {
+                                                        ::peg::RuleResult::Matched(__pos, ())
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                }
+                                            }
+                                            ::peg::RuleResult::Failed => {
+                                                __err_state.mark_failure(__pos, "\"impl\"");
+                                                ::peg::RuleResult::Failed
+                                            }
+                                        };
+                                    match __choice_res {
+                                        ::peg::RuleResult::Matched(__pos, __value) => {
+                                            ::peg::RuleResult::Matched(__pos, __value)
+                                        }
+                                        ::peg::RuleResult::Failed => {
+                                            let __choice_res =
+                                                match ::peg::ParseLiteral::parse_string_literal(
+                                                    __input, __pos, "(",
+                                                ) {
+                                                    ::peg::RuleResult::Matched(__pos, __val) => {
+                                                        let __seq_res = {
+                                                            let mut __repeat_pos = __pos;
+                                                            let mut __repeat_value = vec![];
+                                                            loop {
+                                                                let __pos = __repeat_pos;
+                                                                let __pos = if __repeat_value
+                                                                    .is_empty()
+                                                                {
+                                                                    __pos
+                                                                } else {
+                                                                    let __sep_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ",") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\",\"") ; :: peg :: RuleResult :: Failed } } ;
+                                                                    match __sep_res { :: peg :: RuleResult :: Matched (__newpos , _) => { __newpos } , :: peg :: RuleResult :: Failed => break , }
+                                                                };
+                                                                let __step_res = match __parse_rust_type (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ;
+                                                                match __step_res {
+                                                                    ::peg::RuleResult::Matched(
+                                                                        __newpos,
+                                                                        __value,
+                                                                    ) => {
+                                                                        __repeat_pos = __newpos;
+                                                                        __repeat_value
+                                                                            .push(__value);
+                                                                    }
+                                                                    ::peg::RuleResult::Failed => {
+                                                                        break;
+                                                                    }
+                                                                }
+                                                            }
+                                                            ::peg::RuleResult::Matched(
+                                                                __repeat_pos,
+                                                                (),
+                                                            )
+                                                        };
+                                                        match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ")") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\")\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        __err_state.mark_failure(__pos, "\"(\"");
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                };
+                                            match __choice_res {
+                                                ::peg::RuleResult::Matched(__pos, __value) => {
+                                                    ::peg::RuleResult::Matched(__pos, __value)
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    match __parse_rust_ty_path(
+                                                        __input,
+                                                        __state,
+                                                        __err_state,
+                                                        __pos,
+                                                    ) {
+                                                        ::peg::RuleResult::Matched(pos, _) => {
+                                                            ::peg::RuleResult::Matched(pos, ())
+                                                        }
+                                                        ::peg::RuleResult::Failed => {
+                                                            ::peg::RuleResult::Failed
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    fn __parse_rust_ty_path<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<()> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __seq_res =
+                match match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "::") {
+                    ::peg::RuleResult::Matched(__pos, __val) => {
+                        ::peg::RuleResult::Matched(__pos, __val)
+                    }
+                    ::peg::RuleResult::Failed => {
+                        __err_state.mark_failure(__pos, "\"::\"");
+                        ::peg::RuleResult::Failed
+                    }
+                } {
+                    ::peg::RuleResult::Matched(__newpos, _) => {
+                        ::peg::RuleResult::Matched(__newpos, ())
+                    }
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Matched(__pos, ()),
+                };
+            match __seq_res {
+                ::peg::RuleResult::Matched(__pos, _) => {
+                    let __seq_res = {
+                        let mut __repeat_pos = __pos;
+                        let mut __repeat_value = vec![];
+                        loop {
+                            let __pos = __repeat_pos;
+                            let __pos = if __repeat_value.is_empty() {
+                                __pos
+                            } else {
+                                let __sep_res = match ::peg::ParseLiteral::parse_string_literal(
+                                    __input, __pos, "::",
+                                ) {
+                                    ::peg::RuleResult::Matched(__pos, __val) => {
+                                        ::peg::RuleResult::Matched(__pos, __val)
+                                    }
+                                    ::peg::RuleResult::Failed => {
+                                        __err_state.mark_failure(__pos, "\"::\"");
+                                        ::peg::RuleResult::Failed
+                                    }
+                                };
+                                match __sep_res {
+                                    ::peg::RuleResult::Matched(__newpos, _) => __newpos,
+                                    ::peg::RuleResult::Failed => break,
+                                }
+                            };
+                            let __step_res = {
+                                let __seq_res =
+                                    match __parse_IDENT(__input, __state, __err_state, __pos) {
+                                        ::peg::RuleResult::Matched(pos, _) => {
+                                            ::peg::RuleResult::Matched(pos, ())
+                                        }
+                                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                    };
+                                match __seq_res {
+                                    ::peg::RuleResult::Matched(__pos, _) => {
+                                        let __seq_res = match {
+                                            let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "::") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"::\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } ;
+                                            match __seq_res {
+                                                ::peg::RuleResult::Matched(__pos, _) => {
+                                                    match ::peg::ParseLiteral::parse_string_literal(
+                                                        __input, __pos, "<",
+                                                    ) {
+                                                        ::peg::RuleResult::Matched(
+                                                            __pos,
+                                                            __val,
+                                                        ) => {
+                                                            let __seq_res = {
+                                                                let mut __repeat_pos = __pos;
+                                                                let mut __repeat_value = vec![];
+                                                                loop {
+                                                                    let __pos = __repeat_pos;
+                                                                    let __pos = if __repeat_value
+                                                                        .is_empty()
+                                                                    {
+                                                                        __pos
+                                                                    } else {
+                                                                        let __sep_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ",") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\",\"") ; :: peg :: RuleResult :: Failed } } ;
+                                                                        match __sep_res { :: peg :: RuleResult :: Matched (__newpos , _) => { __newpos } , :: peg :: RuleResult :: Failed => break , }
+                                                                    };
+                                                                    let __step_res = {
+                                                                        let __choice_res = match __parse_LIFETIME (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ;
+                                                                        match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => { let __choice_res = match __parse_rust_type (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => { let __choice_res = match __parse_BRACE_GROUP (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => match __parse_LITERAL (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } } } }
+                                                                    };
+                                                                    match __step_res { :: peg :: RuleResult :: Matched (__newpos , __value) => { __repeat_pos = __newpos ; __repeat_value . push (__value) ; } , :: peg :: RuleResult :: Failed => { break ; } }
+                                                                }
+                                                                if __repeat_value.len() >= 1 {
+                                                                    ::peg::RuleResult::Matched(
+                                                                        __repeat_pos,
+                                                                        (),
+                                                                    )
+                                                                } else {
+                                                                    ::peg::RuleResult::Failed
+                                                                }
+                                                            };
+                                                            match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ">") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\">\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                                        }
+                                                        ::peg::RuleResult::Failed => {
+                                                            __err_state
+                                                                .mark_failure(__pos, "\"<\"");
+                                                            ::peg::RuleResult::Failed
+                                                        }
+                                                    }
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    ::peg::RuleResult::Failed
+                                                }
+                                            }
+                                        } {
+                                            ::peg::RuleResult::Matched(__newpos, _) => {
+                                                ::peg::RuleResult::Matched(__newpos, ())
+                                            }
+                                            ::peg::RuleResult::Failed => {
+                                                ::peg::RuleResult::Matched(__pos, ())
+                                            }
+                                        };
+                                        match __seq_res {
+                                            ::peg::RuleResult::Matched(__pos, _) => {
+                                                ::peg::RuleResult::Matched(__pos, ())
+                                            }
+                                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                        }
+                                    }
+                                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                }
+                            };
+                            match __step_res {
+                                ::peg::RuleResult::Matched(__newpos, __value) => {
+                                    __repeat_pos = __newpos;
+                                    __repeat_value.push(__value);
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    break;
+                                }
+                            }
+                        }
+                        if __repeat_value.len() >= 1 {
+                            ::peg::RuleResult::Matched(__repeat_pos, ())
+                        } else {
+                            ::peg::RuleResult::Failed
+                        }
+                    };
+                    match __seq_res {
+                        ::peg::RuleResult::Matched(__pos, _) => {
+                            ::peg::RuleResult::Matched(__pos, ())
+                        }
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                    }
+                }
+                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+            }
+        }
+    }
+    fn __parse_rust_ty_params<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<Vec<TokenStream>> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "<") {
+            ::peg::RuleResult::Matched(__pos, __val) => {
+                let __seq_res = {
+                    let mut __repeat_pos = __pos;
+                    let mut __repeat_value = vec![];
+                    loop {
+                        let __pos = __repeat_pos;
+                        let __pos = if __repeat_value.is_empty() {
+                            __pos
+                        } else {
+                            let __sep_res = match ::peg::ParseLiteral::parse_string_literal(
+                                __input, __pos, ",",
+                            ) {
+                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                    ::peg::RuleResult::Matched(__pos, __val)
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    __err_state.mark_failure(__pos, "\",\"");
+                                    ::peg::RuleResult::Failed
+                                }
+                            };
+                            match __sep_res {
+                                ::peg::RuleResult::Matched(__newpos, _) => __newpos,
+                                ::peg::RuleResult::Failed => break,
+                            }
+                        };
+                        let __step_res = {
+                            let str_start = __pos;
+                            match match __parse_rust_generic_param(
+                                __input,
+                                __state,
+                                __err_state,
+                                __pos,
+                            ) {
+                                ::peg::RuleResult::Matched(pos, _) => {
+                                    ::peg::RuleResult::Matched(pos, ())
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                            } {
+                                ::peg::RuleResult::Matched(__newpos, _) => {
+                                    ::peg::RuleResult::Matched(
+                                        __newpos,
+                                        ::peg::ParseSlice::parse_slice(
+                                            __input, str_start, __newpos,
+                                        ),
+                                    )
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                            }
+                        };
+                        match __step_res {
+                            ::peg::RuleResult::Matched(__newpos, __value) => {
+                                __repeat_pos = __newpos;
+                                __repeat_value.push(__value);
+                            }
+                            ::peg::RuleResult::Failed => {
+                                break;
+                            }
+                        }
+                    }
+                    if __repeat_value.len() >= 1 {
+                        ::peg::RuleResult::Matched(__repeat_pos, __repeat_value)
+                    } else {
+                        ::peg::RuleResult::Failed
+                    }
+                };
+                match __seq_res {
+                    ::peg::RuleResult::Matched(__pos, p) => {
+                        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, ">") {
+                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                ::peg::RuleResult::Matched(__pos, (|| p)())
+                            }
+                            ::peg::RuleResult::Failed => {
+                                __err_state.mark_failure(__pos, "\">\"");
+                                ::peg::RuleResult::Failed
+                            }
+                        }
+                    }
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                }
+            }
+            ::peg::RuleResult::Failed => {
+                __err_state.mark_failure(__pos, "\"<\"");
+                ::peg::RuleResult::Failed
+            }
+        }
+    }
+    fn __parse_rust_generic_param<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<()> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __choice_res = {
+                let __seq_res = match __parse_LIFETIME(__input, __state, __err_state, __pos) {
+                    ::peg::RuleResult::Matched(pos, _) => ::peg::RuleResult::Matched(pos, ()),
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                };
+                match __seq_res {
+                    ::peg::RuleResult::Matched(__pos, _) => {
+                        let __seq_res = match match ::peg::ParseLiteral::parse_string_literal(
+                            __input, __pos, ":",
+                        ) {
+                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                let __seq_res = {
+                                    let mut __repeat_pos = __pos;
+                                    let mut __repeat_value = vec![];
+                                    loop {
+                                        let __pos = __repeat_pos;
+                                        let __pos = if __repeat_value.is_empty() {
+                                            __pos
+                                        } else {
+                                            let __sep_res =
+                                                match ::peg::ParseLiteral::parse_string_literal(
+                                                    __input, __pos, "+",
+                                                ) {
+                                                    ::peg::RuleResult::Matched(__pos, __val) => {
+                                                        ::peg::RuleResult::Matched(__pos, __val)
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        __err_state.mark_failure(__pos, "\"+\"");
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                };
+                                            match __sep_res {
+                                                ::peg::RuleResult::Matched(__newpos, _) => __newpos,
+                                                ::peg::RuleResult::Failed => break,
+                                            }
+                                        };
+                                        let __step_res = match __parse_LIFETIME(
+                                            __input,
+                                            __state,
+                                            __err_state,
+                                            __pos,
+                                        ) {
+                                            ::peg::RuleResult::Matched(pos, _) => {
+                                                ::peg::RuleResult::Matched(pos, ())
+                                            }
+                                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                        };
+                                        match __step_res {
+                                            ::peg::RuleResult::Matched(__newpos, __value) => {
+                                                __repeat_pos = __newpos;
+                                                __repeat_value.push(__value);
+                                            }
+                                            ::peg::RuleResult::Failed => {
+                                                break;
+                                            }
+                                        }
+                                    }
+                                    if __repeat_value.len() >= 1 {
+                                        ::peg::RuleResult::Matched(__repeat_pos, ())
+                                    } else {
+                                        ::peg::RuleResult::Failed
+                                    }
+                                };
+                                match __seq_res {
+                                    ::peg::RuleResult::Matched(__pos, _) => {
+                                        ::peg::RuleResult::Matched(__pos, ())
+                                    }
+                                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                }
+                            }
+                            ::peg::RuleResult::Failed => {
+                                __err_state.mark_failure(__pos, "\":\"");
+                                ::peg::RuleResult::Failed
+                            }
+                        } {
+                            ::peg::RuleResult::Matched(__newpos, _) => {
+                                ::peg::RuleResult::Matched(__newpos, ())
+                            }
+                            ::peg::RuleResult::Failed => ::peg::RuleResult::Matched(__pos, ()),
+                        };
+                        match __seq_res {
+                            ::peg::RuleResult::Matched(__pos, _) => {
+                                ::peg::RuleResult::Matched(__pos, ())
+                            }
+                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                        }
+                    }
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                }
+            };
+            match __choice_res {
+                ::peg::RuleResult::Matched(__pos, __value) => {
+                    ::peg::RuleResult::Matched(__pos, __value)
+                }
+                ::peg::RuleResult::Failed => {
+                    let __seq_res = match __parse_IDENT(__input, __state, __err_state, __pos) {
+                        ::peg::RuleResult::Matched(pos, _) => ::peg::RuleResult::Matched(pos, ()),
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                    };
+                    match __seq_res {
+                        ::peg::RuleResult::Matched(__pos, _) => {
+                            let __seq_res = match match ::peg::ParseLiteral::parse_string_literal(
+                                __input, __pos, ":",
+                            ) {
+                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                    let __seq_res = {
+                                        let mut __repeat_pos = __pos;
+                                        let mut __repeat_value = vec![];
+                                        loop {
+                                            let __pos = __repeat_pos;
+                                            let __pos = if __repeat_value.is_empty() {
+                                                __pos
+                                            } else {
+                                                let __sep_res =
+                                                    match ::peg::ParseLiteral::parse_string_literal(
+                                                        __input, __pos, "+",
+                                                    ) {
+                                                        ::peg::RuleResult::Matched(
+                                                            __pos,
+                                                            __val,
+                                                        ) => {
+                                                            ::peg::RuleResult::Matched(__pos, __val)
+                                                        }
+                                                        ::peg::RuleResult::Failed => {
+                                                            __err_state
+                                                                .mark_failure(__pos, "\"+\"");
+                                                            ::peg::RuleResult::Failed
+                                                        }
+                                                    };
+                                                match __sep_res {
+                                                    ::peg::RuleResult::Matched(__newpos, _) => {
+                                                        __newpos
+                                                    }
+                                                    ::peg::RuleResult::Failed => break,
+                                                }
+                                            };
+                                            let __step_res = {
+                                                let __choice_res = match __parse_LIFETIME(
+                                                    __input,
+                                                    __state,
+                                                    __err_state,
+                                                    __pos,
+                                                ) {
+                                                    ::peg::RuleResult::Matched(pos, _) => {
+                                                        ::peg::RuleResult::Matched(pos, ())
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                };
+                                                match __choice_res {
+                                                    ::peg::RuleResult::Matched(__pos, __value) => {
+                                                        ::peg::RuleResult::Matched(__pos, __value)
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "?") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"?\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } ;
+                                                        match __seq_res {
+                                                            ::peg::RuleResult::Matched(
+                                                                __pos,
+                                                                _,
+                                                            ) => {
+                                                                let __seq_res = match __parse_rust_ty_path (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ;
+                                                                match __seq_res {
+                                                                    ::peg::RuleResult::Matched(
+                                                                        __pos,
+                                                                        _,
+                                                                    ) => {
+                                                                        ::peg::RuleResult::Matched(
+                                                                            __pos,
+                                                                            (),
+                                                                        )
+                                                                    }
+                                                                    ::peg::RuleResult::Failed => {
+                                                                        ::peg::RuleResult::Failed
+                                                                    }
+                                                                }
+                                                            }
+                                                            ::peg::RuleResult::Failed => {
+                                                                ::peg::RuleResult::Failed
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                            };
+                                            match __step_res {
+                                                ::peg::RuleResult::Matched(__newpos, __value) => {
+                                                    __repeat_pos = __newpos;
+                                                    __repeat_value.push(__value);
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    break;
+                                                }
+                                            }
+                                        }
+                                        if __repeat_value.len() >= 1 {
+                                            ::peg::RuleResult::Matched(__repeat_pos, ())
+                                        } else {
+                                            ::peg::RuleResult::Failed
+                                        }
+                                    };
+                                    match __seq_res {
+                                        ::peg::RuleResult::Matched(__pos, _) => {
+                                            ::peg::RuleResult::Matched(__pos, ())
+                                        }
+                                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                    }
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    __err_state.mark_failure(__pos, "\":\"");
+                                    ::peg::RuleResult::Failed
+                                }
+                            } {
+                                ::peg::RuleResult::Matched(__newpos, _) => {
+                                    ::peg::RuleResult::Matched(__newpos, ())
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Matched(__pos, ()),
+                            };
+                            match __seq_res {
+                                ::peg::RuleResult::Matched(__pos, _) => {
+                                    ::peg::RuleResult::Matched(__pos, ())
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                            }
+                        }
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                    }
+                }
+            }
+        }
+    }
+    fn __parse_expression<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<SpannedExpr> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        __parse_choice(__input, __state, __err_state, __pos)
+    }
+    fn __parse_choice<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<SpannedExpr> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __seq_res = __parse_sp(__input, __state, __err_state, __pos);
+            match __seq_res {
+                ::peg::RuleResult::Matched(__pos, sp) => {
+                    let __seq_res = {
+                        let mut __repeat_pos = __pos;
+                        let mut __repeat_value = vec![];
+                        loop {
+                            let __pos = __repeat_pos;
+                            let __pos = if __repeat_value.is_empty() {
+                                __pos
+                            } else {
+                                let __sep_res = match ::peg::ParseLiteral::parse_string_literal(
+                                    __input, __pos, "/",
+                                ) {
+                                    ::peg::RuleResult::Matched(__pos, __val) => {
+                                        ::peg::RuleResult::Matched(__pos, __val)
+                                    }
+                                    ::peg::RuleResult::Failed => {
+                                        __err_state.mark_failure(__pos, "\"/\"");
+                                        ::peg::RuleResult::Failed
+                                    }
+                                };
+                                match __sep_res {
+                                    ::peg::RuleResult::Matched(__newpos, _) => __newpos,
+                                    ::peg::RuleResult::Failed => break,
+                                }
+                            };
+                            let __step_res = __parse_sequence(__input, __state, __err_state, __pos);
+                            match __step_res {
+                                ::peg::RuleResult::Matched(__newpos, __value) => {
+                                    __repeat_pos = __newpos;
+                                    __repeat_value.push(__value);
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    break;
+                                }
+                            }
+                        }
+                        if __repeat_value.len() >= 1 {
+                            ::peg::RuleResult::Matched(__repeat_pos, __repeat_value)
+                        } else {
+                            ::peg::RuleResult::Failed
+                        }
+                    };
+                    match __seq_res {
+                        ::peg::RuleResult::Matched(__pos, s) => ::peg::RuleResult::Matched(
+                            __pos,
+                            (|| {
+                                if s.len() == 1 {
+                                    s.into_iter().next().unwrap()
+                                } else {
+                                    ChoiceExpr(s).at(sp)
+                                }
+                            })(),
+                        ),
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                    }
+                }
+                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+            }
+        }
+    }
+    fn __parse_sequence<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<SpannedExpr> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __seq_res = __parse_sp(__input, __state, __err_state, __pos);
+            match __seq_res {
+                ::peg::RuleResult::Matched(__pos, sp) => {
+                    let __seq_res = {
+                        let mut __repeat_pos = __pos;
+                        let mut __repeat_value = vec![];
+                        loop {
+                            let __pos = __repeat_pos;
+                            let __step_res = __parse_labeled(__input, __state, __err_state, __pos);
+                            match __step_res {
+                                ::peg::RuleResult::Matched(__newpos, __value) => {
+                                    __repeat_pos = __newpos;
+                                    __repeat_value.push(__value);
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    break;
+                                }
+                            }
+                        }
+                        ::peg::RuleResult::Matched(__repeat_pos, __repeat_value)
+                    };
+                    match __seq_res {
+                        ::peg::RuleResult::Matched(__pos, elements) => {
+                            let __seq_res =
+                                match __parse_BRACE_GROUP(__input, __state, __err_state, __pos) {
+                                    ::peg::RuleResult::Matched(__newpos, __value) => {
+                                        ::peg::RuleResult::Matched(__newpos, Some(__value))
+                                    }
+                                    ::peg::RuleResult::Failed => {
+                                        ::peg::RuleResult::Matched(__pos, None)
+                                    }
+                                };
+                            match __seq_res {
+                                ::peg::RuleResult::Matched(__pos, code) => {
+                                    ::peg::RuleResult::Matched(
+                                        __pos,
+                                        (|| {
+                                            if let Some(code) = code {
+                                                ActionExpr(elements, Some(code)).at(sp)
+                                            } else if elements.len() != 1 {
+                                                ActionExpr(elements, None).at(sp)
+                                            } else {
+                                                elements.into_iter().next().unwrap().expr
+                                            }
+                                        })(),
+                                    )
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                            }
+                        }
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                    }
+                }
+                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+            }
+        }
+    }
+    fn __parse_labeled<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<TaggedExpr> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __seq_res = match {
+                let __seq_res = __parse_IDENT(__input, __state, __err_state, __pos);
+                match __seq_res {
+                    ::peg::RuleResult::Matched(__pos, l) => {
+                        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, ":") {
+                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                ::peg::RuleResult::Matched(__pos, (|| l)())
+                            }
+                            ::peg::RuleResult::Failed => {
+                                __err_state.mark_failure(__pos, "\":\"");
+                                ::peg::RuleResult::Failed
+                            }
+                        }
+                    }
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                }
+            } {
+                ::peg::RuleResult::Matched(__newpos, __value) => {
+                    ::peg::RuleResult::Matched(__newpos, Some(__value))
+                }
+                ::peg::RuleResult::Failed => ::peg::RuleResult::Matched(__pos, None),
+            };
+            match __seq_res {
+                ::peg::RuleResult::Matched(__pos, label) => {
+                    let __seq_res = __parse_suffixed(__input, __state, __err_state, __pos);
+                    match __seq_res {
+                        ::peg::RuleResult::Matched(__pos, expression) => {
+                            ::peg::RuleResult::Matched(
+                                __pos,
+                                (|| TaggedExpr {
+                                    name: label,
+                                    expr: expression,
+                                })(),
+                            )
+                        }
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                    }
+                }
+                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+            }
+        }
+    }
+    fn __parse_suffixed<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<SpannedExpr> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __choice_res = {
+                let __seq_res = __parse_prefixed(__input, __state, __err_state, __pos);
+                match __seq_res {
+                    ::peg::RuleResult::Matched(__pos, e) => {
+                        let __seq_res = __parse_sp(__input, __state, __err_state, __pos);
+                        match __seq_res {
+                            ::peg::RuleResult::Matched(__pos, sp) => {
+                                match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "?")
+                                {
+                                    ::peg::RuleResult::Matched(__pos, __val) => {
+                                        ::peg::RuleResult::Matched(
+                                            __pos,
+                                            (|| OptionalExpr(Box::new(e)).at(sp))(),
+                                        )
+                                    }
+                                    ::peg::RuleResult::Failed => {
+                                        __err_state.mark_failure(__pos, "\"?\"");
+                                        ::peg::RuleResult::Failed
+                                    }
+                                }
+                            }
+                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                        }
+                    }
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                }
+            };
+            match __choice_res {
+                ::peg::RuleResult::Matched(__pos, __value) => {
+                    ::peg::RuleResult::Matched(__pos, __value)
+                }
+                ::peg::RuleResult::Failed => {
+                    let __choice_res = {
+                        let __seq_res = __parse_prefixed(__input, __state, __err_state, __pos);
+                        match __seq_res {
+                            ::peg::RuleResult::Matched(__pos, e) => {
+                                let __seq_res = __parse_sp(__input, __state, __err_state, __pos);
+                                match __seq_res {
+                                    ::peg::RuleResult::Matched(__pos, sp) => {
+                                        match ::peg::ParseLiteral::parse_string_literal(
+                                            __input, __pos, "**",
+                                        ) {
+                                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                                let __seq_res = __parse_repeatcount(
+                                                    __input,
+                                                    __state,
+                                                    __err_state,
+                                                    __pos,
+                                                );
+                                                match __seq_res {
+                                                    ::peg::RuleResult::Matched(__pos, count) => {
+                                                        let __seq_res = __parse_primary(
+                                                            __input,
+                                                            __state,
+                                                            __err_state,
+                                                            __pos,
+                                                        );
+                                                        match __seq_res {
+                                                            ::peg::RuleResult::Matched(
+                                                                __pos,
+                                                                sep,
+                                                            ) => ::peg::RuleResult::Matched(
+                                                                __pos,
+                                                                (|| {
+                                                                    Repeat {
+                                                                        inner: Box::new(e),
+                                                                        bound: count,
+                                                                        sep: Some(Box::new(sep)),
+                                                                    }
+                                                                    .at(sp)
+                                                                })(
+                                                                ),
+                                                            ),
+                                                            ::peg::RuleResult::Failed => {
+                                                                ::peg::RuleResult::Failed
+                                                            }
+                                                        }
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                }
+                                            }
+                                            ::peg::RuleResult::Failed => {
+                                                __err_state.mark_failure(__pos, "\"**\"");
+                                                ::peg::RuleResult::Failed
+                                            }
+                                        }
+                                    }
+                                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                }
+                            }
+                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                        }
+                    };
+                    match __choice_res {
+                        ::peg::RuleResult::Matched(__pos, __value) => {
+                            ::peg::RuleResult::Matched(__pos, __value)
+                        }
+                        ::peg::RuleResult::Failed => {
+                            let __choice_res = {
+                                let __seq_res =
+                                    __parse_prefixed(__input, __state, __err_state, __pos);
+                                match __seq_res {
+                                    ::peg::RuleResult::Matched(__pos, e) => {
+                                        let __seq_res =
+                                            __parse_sp(__input, __state, __err_state, __pos);
+                                        match __seq_res {
+                                            ::peg::RuleResult::Matched(__pos, sp) => {
+                                                match ::peg::ParseLiteral::parse_string_literal(
+                                                    __input, __pos, "++",
+                                                ) {
+                                                    ::peg::RuleResult::Matched(__pos, __val) => {
+                                                        let __seq_res = __parse_primary(
+                                                            __input,
+                                                            __state,
+                                                            __err_state,
+                                                            __pos,
+                                                        );
+                                                        match __seq_res {
+                                                            ::peg::RuleResult::Matched(
+                                                                __pos,
+                                                                sep,
+                                                            ) => ::peg::RuleResult::Matched(
+                                                                __pos,
+                                                                (|| {
+                                                                    Repeat {
+                                                                        inner: Box::new(e),
+                                                                        bound: BoundedRepeat::Plus,
+                                                                        sep: Some(Box::new(sep)),
+                                                                    }
+                                                                    .at(sp)
+                                                                })(
+                                                                ),
+                                                            ),
+                                                            ::peg::RuleResult::Failed => {
+                                                                ::peg::RuleResult::Failed
+                                                            }
+                                                        }
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        __err_state.mark_failure(__pos, "\"++\"");
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                }
+                                            }
+                                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                        }
+                                    }
+                                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                }
+                            };
+                            match __choice_res {
+                                ::peg::RuleResult::Matched(__pos, __value) => {
+                                    ::peg::RuleResult::Matched(__pos, __value)
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    let __choice_res = {
+                                        let __seq_res =
+                                            __parse_prefixed(__input, __state, __err_state, __pos);
+                                        match __seq_res {
+                                            ::peg::RuleResult::Matched(__pos, e) => {
+                                                let __seq_res = __parse_sp(
+                                                    __input,
+                                                    __state,
+                                                    __err_state,
+                                                    __pos,
+                                                );
+                                                match __seq_res { :: peg :: RuleResult :: Matched (__pos , sp) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "*") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = __parse_repeatcount (__input , __state , __err_state , __pos) ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , count) => { :: peg :: RuleResult :: Matched (__pos , (|| { Repeat { inner : Box :: new (e) , bound : count , sep : None } . at (sp) }) ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"*\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                            }
+                                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                        }
+                                    };
+                                    match __choice_res {
+                                        ::peg::RuleResult::Matched(__pos, __value) => {
+                                            ::peg::RuleResult::Matched(__pos, __value)
+                                        }
+                                        ::peg::RuleResult::Failed => {
+                                            let __choice_res = {
+                                                let __seq_res = __parse_prefixed(
+                                                    __input,
+                                                    __state,
+                                                    __err_state,
+                                                    __pos,
+                                                );
+                                                match __seq_res {
+                                                    ::peg::RuleResult::Matched(__pos, e) => {
+                                                        let __seq_res = __parse_sp(
+                                                            __input,
+                                                            __state,
+                                                            __err_state,
+                                                            __pos,
+                                                        );
+                                                        match __seq_res { :: peg :: RuleResult :: Matched (__pos , sp) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "+") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , (|| { Repeat { inner : Box :: new (e) , bound : BoundedRepeat :: Plus , sep : None } . at (sp) }) ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"+\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                }
+                                            };
+                                            match __choice_res {
+                                                ::peg::RuleResult::Matched(__pos, __value) => {
+                                                    ::peg::RuleResult::Matched(__pos, __value)
+                                                }
+                                                ::peg::RuleResult::Failed => __parse_prefixed(
+                                                    __input,
+                                                    __state,
+                                                    __err_state,
+                                                    __pos,
+                                                ),
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    fn __parse_repeatcount<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<BoundedRepeat> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __choice_res = match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "<")
+            {
+                ::peg::RuleResult::Matched(__pos, __val) => {
+                    let __seq_res = __parse_repeatnum(__input, __state, __err_state, __pos);
+                    match __seq_res {
+                        ::peg::RuleResult::Matched(__pos, n) => {
+                            match ::peg::ParseLiteral::parse_string_literal(__input, __pos, ">") {
+                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                    ::peg::RuleResult::Matched(
+                                        __pos,
+                                        (|| BoundedRepeat::Exact(n))(),
+                                    )
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    __err_state.mark_failure(__pos, "\">\"");
+                                    ::peg::RuleResult::Failed
+                                }
+                            }
+                        }
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                    }
+                }
+                ::peg::RuleResult::Failed => {
+                    __err_state.mark_failure(__pos, "\"<\"");
+                    ::peg::RuleResult::Failed
+                }
+            };
+            match __choice_res {
+                ::peg::RuleResult::Matched(__pos, __value) => {
+                    ::peg::RuleResult::Matched(__pos, __value)
+                }
+                ::peg::RuleResult::Failed => {
+                    let __choice_res = match ::peg::ParseLiteral::parse_string_literal(
+                        __input, __pos, "<",
+                    ) {
+                        ::peg::RuleResult::Matched(__pos, __val) => {
+                            let __seq_res =
+                                match __parse_repeatnum(__input, __state, __err_state, __pos) {
+                                    ::peg::RuleResult::Matched(__newpos, __value) => {
+                                        ::peg::RuleResult::Matched(__newpos, Some(__value))
+                                    }
+                                    ::peg::RuleResult::Failed => {
+                                        ::peg::RuleResult::Matched(__pos, None)
+                                    }
+                                };
+                            match __seq_res {
+                                ::peg::RuleResult::Matched(__pos, min) => {
+                                    match ::peg::ParseLiteral::parse_string_literal(
+                                        __input, __pos, ",",
+                                    ) {
+                                        ::peg::RuleResult::Matched(__pos, __val) => {
+                                            let __seq_res = match __parse_repeatnum(
+                                                __input,
+                                                __state,
+                                                __err_state,
+                                                __pos,
+                                            ) {
+                                                ::peg::RuleResult::Matched(__newpos, __value) => {
+                                                    ::peg::RuleResult::Matched(
+                                                        __newpos,
+                                                        Some(__value),
+                                                    )
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    ::peg::RuleResult::Matched(__pos, None)
+                                                }
+                                            };
+                                            match __seq_res {
+                                                ::peg::RuleResult::Matched(__pos, max) => {
+                                                    match ::peg::ParseLiteral::parse_string_literal(
+                                                        __input, __pos, ">",
+                                                    ) {
+                                                        ::peg::RuleResult::Matched(
+                                                            __pos,
+                                                            __val,
+                                                        ) => ::peg::RuleResult::Matched(
+                                                            __pos,
+                                                            (|| BoundedRepeat::Both(min, max))(),
+                                                        ),
+                                                        ::peg::RuleResult::Failed => {
+                                                            __err_state
+                                                                .mark_failure(__pos, "\">\"");
+                                                            ::peg::RuleResult::Failed
+                                                        }
+                                                    }
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    ::peg::RuleResult::Failed
+                                                }
+                                            }
+                                        }
+                                        ::peg::RuleResult::Failed => {
+                                            __err_state.mark_failure(__pos, "\",\"");
+                                            ::peg::RuleResult::Failed
+                                        }
+                                    }
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                            }
+                        }
+                        ::peg::RuleResult::Failed => {
+                            __err_state.mark_failure(__pos, "\"<\"");
+                            ::peg::RuleResult::Failed
+                        }
+                    };
+                    match __choice_res {
+                        ::peg::RuleResult::Matched(__pos, __value) => {
+                            ::peg::RuleResult::Matched(__pos, __value)
+                        }
+                        ::peg::RuleResult::Failed => {
+                            ::peg::RuleResult::Matched(__pos, (|| BoundedRepeat::None)())
+                        }
+                    }
+                }
+            }
+        }
+    }
+    fn __parse_repeatnum<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<TokenStream> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let str_start = __pos;
+            match {
+                let __choice_res = match __parse_INTEGER(__input, __state, __err_state, __pos) {
+                    ::peg::RuleResult::Matched(pos, _) => ::peg::RuleResult::Matched(pos, ()),
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                };
+                match __choice_res {
+                    ::peg::RuleResult::Matched(__pos, __value) => {
+                        ::peg::RuleResult::Matched(__pos, __value)
+                    }
+                    ::peg::RuleResult::Failed => {
+                        match __parse_BRACE_GROUP(__input, __state, __err_state, __pos) {
+                            ::peg::RuleResult::Matched(pos, _) => {
+                                ::peg::RuleResult::Matched(pos, ())
+                            }
+                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                        }
+                    }
+                }
+            } {
+                ::peg::RuleResult::Matched(__newpos, _) => ::peg::RuleResult::Matched(
+                    __newpos,
+                    ::peg::ParseSlice::parse_slice(__input, str_start, __newpos),
+                ),
+                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+            }
+        }
+    }
+    fn __parse_prefixed<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<SpannedExpr> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __choice_res = {
+                let __seq_res = __parse_sp(__input, __state, __err_state, __pos);
+                match __seq_res {
+                    ::peg::RuleResult::Matched(__pos, sp) => {
+                        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "$") {
+                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                let __seq_res =
+                                    __parse_primary(__input, __state, __err_state, __pos);
+                                match __seq_res {
+                                    ::peg::RuleResult::Matched(__pos, expression) => {
+                                        ::peg::RuleResult::Matched(
+                                            __pos,
+                                            (|| MatchStrExpr(Box::new(expression)).at(sp))(),
+                                        )
+                                    }
+                                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                }
+                            }
+                            ::peg::RuleResult::Failed => {
+                                __err_state.mark_failure(__pos, "\"$\"");
+                                ::peg::RuleResult::Failed
+                            }
+                        }
+                    }
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                }
+            };
+            match __choice_res {
+                ::peg::RuleResult::Matched(__pos, __value) => {
+                    ::peg::RuleResult::Matched(__pos, __value)
+                }
+                ::peg::RuleResult::Failed => {
+                    let __choice_res = {
+                        let __seq_res = __parse_sp(__input, __state, __err_state, __pos);
+                        match __seq_res {
+                            ::peg::RuleResult::Matched(__pos, sp) => {
+                                match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "&")
+                                {
+                                    ::peg::RuleResult::Matched(__pos, __val) => {
+                                        let __seq_res =
+                                            __parse_primary(__input, __state, __err_state, __pos);
+                                        match __seq_res {
+                                            ::peg::RuleResult::Matched(__pos, expression) => {
+                                                ::peg::RuleResult::Matched(
+                                                    __pos,
+                                                    (|| PosAssertExpr(Box::new(expression)).at(sp))(
+                                                    ),
+                                                )
+                                            }
+                                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                        }
+                                    }
+                                    ::peg::RuleResult::Failed => {
+                                        __err_state.mark_failure(__pos, "\"&\"");
+                                        ::peg::RuleResult::Failed
+                                    }
+                                }
+                            }
+                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                        }
+                    };
+                    match __choice_res {
+                        ::peg::RuleResult::Matched(__pos, __value) => {
+                            ::peg::RuleResult::Matched(__pos, __value)
+                        }
+                        ::peg::RuleResult::Failed => {
+                            let __choice_res = {
+                                let __seq_res = __parse_sp(__input, __state, __err_state, __pos);
+                                match __seq_res {
+                                    ::peg::RuleResult::Matched(__pos, sp) => {
+                                        match ::peg::ParseLiteral::parse_string_literal(
+                                            __input, __pos, "!",
+                                        ) {
+                                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                                let __seq_res = __parse_primary(
+                                                    __input,
+                                                    __state,
+                                                    __err_state,
+                                                    __pos,
+                                                );
+                                                match __seq_res {
+                                                    ::peg::RuleResult::Matched(
+                                                        __pos,
+                                                        expression,
+                                                    ) => ::peg::RuleResult::Matched(
+                                                        __pos,
+                                                        (|| {
+                                                            NegAssertExpr(Box::new(expression))
+                                                                .at(sp)
+                                                        })(
+                                                        ),
+                                                    ),
+                                                    ::peg::RuleResult::Failed => {
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                }
+                                            }
+                                            ::peg::RuleResult::Failed => {
+                                                __err_state.mark_failure(__pos, "\"!\"");
+                                                ::peg::RuleResult::Failed
+                                            }
+                                        }
+                                    }
+                                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                }
+                            };
+                            match __choice_res {
+                                ::peg::RuleResult::Matched(__pos, __value) => {
+                                    ::peg::RuleResult::Matched(__pos, __value)
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    __parse_primary(__input, __state, __err_state, __pos)
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    fn __parse_primary<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<SpannedExpr> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        if let Some(entry) = __state.primary_cache.get(&__pos) {
+            return entry.clone();
+        }
+        let __rule_result = {
+            let __choice_res = {
+                let __seq_res = __parse_sp(__input, __state, __err_state, __pos);
+                match __seq_res {
+                    ::peg::RuleResult::Matched(__pos, sp) => {
+                        match ::peg::ParseLiteral::parse_string_literal(
+                            __input,
+                            __pos,
+                            "precedence",
+                        ) {
+                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "!")
+                                {
+                                    ::peg::RuleResult::Matched(__pos, __val) => {
+                                        match ::peg::ParseLiteral::parse_string_literal(
+                                            __input, __pos, "{",
+                                        ) {
+                                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                                let __seq_res = {
+                                                    let mut __repeat_pos = __pos;
+                                                    let mut __repeat_value = vec![];
+                                                    loop {
+                                                        let __pos = __repeat_pos;
+                                                        let __pos = if __repeat_value.is_empty() {
+                                                            __pos
+                                                        } else {
+                                                            let __sep_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "--") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"--\"") ; :: peg :: RuleResult :: Failed } } ;
+                                                            match __sep_res {
+                                                                ::peg::RuleResult::Matched(
+                                                                    __newpos,
+                                                                    _,
+                                                                ) => __newpos,
+                                                                ::peg::RuleResult::Failed => break,
+                                                            }
+                                                        };
+                                                        let __step_res = __parse_precedence_level(
+                                                            __input,
+                                                            __state,
+                                                            __err_state,
+                                                            __pos,
+                                                        );
+                                                        match __step_res {
+                                                            ::peg::RuleResult::Matched(
+                                                                __newpos,
+                                                                __value,
+                                                            ) => {
+                                                                __repeat_pos = __newpos;
+                                                                __repeat_value.push(__value);
+                                                            }
+                                                            ::peg::RuleResult::Failed => {
+                                                                break;
+                                                            }
+                                                        }
+                                                    }
+                                                    ::peg::RuleResult::Matched(
+                                                        __repeat_pos,
+                                                        __repeat_value,
+                                                    )
+                                                };
+                                                match __seq_res { :: peg :: RuleResult :: Matched (__pos , levels) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "}") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , (|| { PrecedenceExpr { levels : levels } . at (sp) }) ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"}\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                            }
+                                            ::peg::RuleResult::Failed => {
+                                                __err_state.mark_failure(__pos, "\"{\"");
+                                                ::peg::RuleResult::Failed
+                                            }
+                                        }
+                                    }
+                                    ::peg::RuleResult::Failed => {
+                                        __err_state.mark_failure(__pos, "\"!\"");
+                                        ::peg::RuleResult::Failed
+                                    }
+                                }
+                            }
+                            ::peg::RuleResult::Failed => {
+                                __err_state.mark_failure(__pos, "\"precedence\"");
+                                ::peg::RuleResult::Failed
+                            }
+                        }
+                    }
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                }
+            };
+            match __choice_res {
+                ::peg::RuleResult::Matched(__pos, __value) => {
+                    ::peg::RuleResult::Matched(__pos, __value)
+                }
+                ::peg::RuleResult::Failed => {
+                    let __choice_res = {
+                        let __seq_res = __parse_sp(__input, __state, __err_state, __pos);
+                        match __seq_res { :: peg :: RuleResult :: Matched (__pos , sp) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "position") { :: peg :: RuleResult :: Matched (__pos , __val) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "!") { :: peg :: RuleResult :: Matched (__pos , __val) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "(") { :: peg :: RuleResult :: Matched (__pos , __val) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ")") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , (|| { PositionExpr . at (sp) }) ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\")\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"(\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"!\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"position\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                    };
+                    match __choice_res {
+                        ::peg::RuleResult::Matched(__pos, __value) => {
+                            ::peg::RuleResult::Matched(__pos, __value)
+                        }
+                        ::peg::RuleResult::Failed => {
+                            let __choice_res = {
+                                let __seq_res = __parse_sp(__input, __state, __err_state, __pos);
+                                match __seq_res { :: peg :: RuleResult :: Matched (__pos , sp) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "quiet") { :: peg :: RuleResult :: Matched (__pos , __val) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "!") { :: peg :: RuleResult :: Matched (__pos , __val) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "{") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = __parse_expression (__input , __state , __err_state , __pos) ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , e) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "}") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , (|| { QuietExpr (Box :: new (e)) . at (sp) }) ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"}\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"{\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"!\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"quiet\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                            };
+                            match __choice_res {
+                                ::peg::RuleResult::Matched(__pos, __value) => {
+                                    ::peg::RuleResult::Matched(__pos, __value)
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    let __choice_res = {
+                                        let __seq_res =
+                                            __parse_sp(__input, __state, __err_state, __pos);
+                                        match __seq_res { :: peg :: RuleResult :: Matched (__pos , sp) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "expected") { :: peg :: RuleResult :: Matched (__pos , __val) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "!") { :: peg :: RuleResult :: Matched (__pos , __val) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "(") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = __parse_LITERAL (__input , __state , __err_state , __pos) ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , s) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ")") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , (|| { FailExpr (s) . at (sp) }) ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\")\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"(\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"!\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"expected\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                    };
+                                    match __choice_res {
+                                        ::peg::RuleResult::Matched(__pos, __value) => {
+                                            ::peg::RuleResult::Matched(__pos, __value)
+                                        }
+                                        ::peg::RuleResult::Failed => {
+                                            let __choice_res = {
+                                                let __seq_res = {
+                                                    __err_state.suppress_fail += 1;
+                                                    let __assert_res = {
+                                                        let __choice_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "_") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"_\"") ; :: peg :: RuleResult :: Failed } } ;
+                                                        match __choice_res {
+                                                            ::peg::RuleResult::Matched(
+                                                                __pos,
+                                                                __value,
+                                                            ) => ::peg::RuleResult::Matched(
+                                                                __pos, __value,
+                                                            ),
+                                                            ::peg::RuleResult::Failed => {
+                                                                let __choice_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "__") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"__\"") ; :: peg :: RuleResult :: Failed } } ;
+                                                                match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "___") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"___\"") ; :: peg :: RuleResult :: Failed } } }
+                                                            }
+                                                        }
+                                                    };
+                                                    __err_state.suppress_fail -= 1;
+                                                    match __assert_res {
+                                                        ::peg::RuleResult::Matched(_, __value) => {
+                                                            ::peg::RuleResult::Matched(
+                                                                __pos, __value,
+                                                            )
+                                                        }
+                                                        ::peg::RuleResult::Failed => {
+                                                            ::peg::RuleResult::Failed
+                                                        }
+                                                    }
+                                                };
+                                                match __seq_res {
+                                                    ::peg::RuleResult::Matched(__pos, _) => {
+                                                        let __seq_res = __parse_sp(
+                                                            __input,
+                                                            __state,
+                                                            __err_state,
+                                                            __pos,
+                                                        );
+                                                        match __seq_res {
+                                                            ::peg::RuleResult::Matched(
+                                                                __pos,
+                                                                sp,
+                                                            ) => {
+                                                                let __seq_res = __parse_IDENT(
+                                                                    __input,
+                                                                    __state,
+                                                                    __err_state,
+                                                                    __pos,
+                                                                );
+                                                                match __seq_res {
+                                                                    ::peg::RuleResult::Matched(
+                                                                        __pos,
+                                                                        name,
+                                                                    ) => {
+                                                                        ::peg::RuleResult::Matched(
+                                                                            __pos,
+                                                                            (|| {
+                                                                                RuleExpr(
+                                                                                    name,
+                                                                                    Vec::new(),
+                                                                                )
+                                                                                .at(sp)
+                                                                            })(
+                                                                            ),
+                                                                        )
+                                                                    }
+                                                                    ::peg::RuleResult::Failed => {
+                                                                        ::peg::RuleResult::Failed
+                                                                    }
+                                                                }
+                                                            }
+                                                            ::peg::RuleResult::Failed => {
+                                                                ::peg::RuleResult::Failed
+                                                            }
+                                                        }
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                }
+                                            };
+                                            match __choice_res {
+                                                ::peg::RuleResult::Matched(__pos, __value) => {
+                                                    ::peg::RuleResult::Matched(__pos, __value)
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    let __choice_res = {
+                                                        let __seq_res = __parse_sp(
+                                                            __input,
+                                                            __state,
+                                                            __err_state,
+                                                            __pos,
+                                                        );
+                                                        match __seq_res {
+                                                            ::peg::RuleResult::Matched(
+                                                                __pos,
+                                                                sp,
+                                                            ) => {
+                                                                let __seq_res = __parse_IDENT(
+                                                                    __input,
+                                                                    __state,
+                                                                    __err_state,
+                                                                    __pos,
+                                                                );
+                                                                match __seq_res { :: peg :: RuleResult :: Matched (__pos , name) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "(") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = { let mut __repeat_pos = __pos ; let mut __repeat_value = vec ! () ; loop { let __pos = __repeat_pos ; let __pos = if __repeat_value . is_empty () { __pos } else { let __sep_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ",") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\",\"") ; :: peg :: RuleResult :: Failed } } ; match __sep_res { :: peg :: RuleResult :: Matched (__newpos , _) => { __newpos } , :: peg :: RuleResult :: Failed => break , } } ; let __step_res = __parse_rule_arg (__input , __state , __err_state , __pos) ; match __step_res { :: peg :: RuleResult :: Matched (__newpos , __value) => { __repeat_pos = __newpos ; __repeat_value . push (__value) ; } , :: peg :: RuleResult :: Failed => { break ; } } } :: peg :: RuleResult :: Matched (__repeat_pos , __repeat_value) } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , args) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ")") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , (|| { RuleExpr (name , args) . at (sp) }) ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\")\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"(\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                                            }
+                                                            ::peg::RuleResult::Failed => {
+                                                                ::peg::RuleResult::Failed
+                                                            }
+                                                        }
+                                                    };
+                                                    match __choice_res {
+                                                        ::peg::RuleResult::Matched(
+                                                            __pos,
+                                                            __value,
+                                                        ) => ::peg::RuleResult::Matched(
+                                                            __pos, __value,
+                                                        ),
+                                                        ::peg::RuleResult::Failed => {
+                                                            let __choice_res = {
+                                                                let __seq_res = __parse_sp(
+                                                                    __input,
+                                                                    __state,
+                                                                    __err_state,
+                                                                    __pos,
+                                                                );
+                                                                match __seq_res {
+                                                                    ::peg::RuleResult::Matched(
+                                                                        __pos,
+                                                                        sp,
+                                                                    ) => {
+                                                                        let __seq_res =
+                                                                            __parse_LITERAL(
+                                                                                __input,
+                                                                                __state,
+                                                                                __err_state,
+                                                                                __pos,
+                                                                            );
+                                                                        match __seq_res { :: peg :: RuleResult :: Matched (__pos , l) => { :: peg :: RuleResult :: Matched (__pos , (|| { LiteralExpr (l) . at (sp) }) ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                                                    }
+                                                                    ::peg::RuleResult::Failed => {
+                                                                        ::peg::RuleResult::Failed
+                                                                    }
+                                                                }
+                                                            };
+                                                            match __choice_res {
+                                                                ::peg::RuleResult::Matched(
+                                                                    __pos,
+                                                                    __value,
+                                                                ) => ::peg::RuleResult::Matched(
+                                                                    __pos, __value,
+                                                                ),
+                                                                ::peg::RuleResult::Failed => {
+                                                                    let __choice_res = {
+                                                                        let __seq_res = __parse_sp(
+                                                                            __input,
+                                                                            __state,
+                                                                            __err_state,
+                                                                            __pos,
+                                                                        );
+                                                                        match __seq_res { :: peg :: RuleResult :: Matched (__pos , sp) => { { let __seq_res = __parse_BRACKET_GROUP (__input , __state , __err_state , __pos) ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , p) => { :: peg :: RuleResult :: Matched (__pos , (|| { PatternExpr (p) . at (sp) }) ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                                                    };
+                                                                    match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => { let __choice_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "(") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = __parse_sp (__input , __state , __err_state , __pos) ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , sp) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "@") { :: peg :: RuleResult :: Matched (__pos , __val) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ")") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , (|| { MarkerExpr (true) . at (sp) }) ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\")\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"@\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"(\"") ; :: peg :: RuleResult :: Failed } } ; match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => { let __choice_res = { let __seq_res = __parse_sp (__input , __state , __err_state , __pos) ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , sp) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "@") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , (|| { MarkerExpr (false) . at (sp) }) ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"@\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } ; match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => { let __choice_res = { let __seq_res = __parse_sp (__input , __state , __err_state , __pos) ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , sp) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "##") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = __parse_IDENT (__input , __state , __err_state , __pos) ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , method) => { { let __seq_res = __parse_PAREN_GROUP (__input , __state , __err_state , __pos) ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , args) => { :: peg :: RuleResult :: Matched (__pos , (|| { MethodExpr (method , args . stream ()) . at (sp) }) ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"##\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } ; match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "(") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = __parse_expression (__input , __state , __err_state , __pos) ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , expression) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ")") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , (|| { expression }) ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\")\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"(\"") ; :: peg :: RuleResult :: Failed } } } } } } } } }
+                                                                }
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        };
+        __state.primary_cache.insert(__pos, __rule_result.clone());
+        __rule_result
+    }
+    fn __parse_rule_arg<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<RuleArg> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __choice_res = match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "<")
+            {
+                ::peg::RuleResult::Matched(__pos, __val) => {
+                    let __seq_res = __parse_expression(__input, __state, __err_state, __pos);
+                    match __seq_res {
+                        ::peg::RuleResult::Matched(__pos, e) => {
+                            match ::peg::ParseLiteral::parse_string_literal(__input, __pos, ">") {
+                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                    ::peg::RuleResult::Matched(__pos, (|| RuleArg::Peg(e))())
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    __err_state.mark_failure(__pos, "\">\"");
+                                    ::peg::RuleResult::Failed
+                                }
+                            }
+                        }
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                    }
+                }
+                ::peg::RuleResult::Failed => {
+                    __err_state.mark_failure(__pos, "\"<\"");
+                    ::peg::RuleResult::Failed
+                }
+            };
+            match __choice_res {
+                ::peg::RuleResult::Matched(__pos, __value) => {
+                    ::peg::RuleResult::Matched(__pos, __value)
+                }
+                ::peg::RuleResult::Failed => {
+                    let __seq_res = {
+                        let str_start = __pos;
+                        match {
+                            let mut __repeat_pos = __pos;
+                            let mut __repeat_value = vec![];
+                            loop {
+                                let __pos = __repeat_pos;
+                                let __step_res = __input.eat_until(__pos, ',');
+                                match __step_res {
+                                    ::peg::RuleResult::Matched(__newpos, __value) => {
+                                        __repeat_pos = __newpos;
+                                        __repeat_value.push(__value);
+                                    }
+                                    ::peg::RuleResult::Failed => {
+                                        break;
+                                    }
+                                }
+                            }
+                            if __repeat_value.len() >= 1 {
+                                ::peg::RuleResult::Matched(__repeat_pos, ())
+                            } else {
+                                ::peg::RuleResult::Failed
+                            }
+                        } {
+                            ::peg::RuleResult::Matched(__newpos, _) => ::peg::RuleResult::Matched(
+                                __newpos,
+                                ::peg::ParseSlice::parse_slice(__input, str_start, __newpos),
+                            ),
+                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                        }
+                    };
+                    match __seq_res {
+                        ::peg::RuleResult::Matched(__pos, tt) => {
+                            ::peg::RuleResult::Matched(__pos, (|| RuleArg::Rust(tt))())
+                        }
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                    }
+                }
+            }
+        }
+    }
+    fn __parse_precedence_level<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<PrecedenceLevel> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __seq_res = {
+                let mut __repeat_pos = __pos;
+                let mut __repeat_value = vec![];
+                loop {
+                    let __pos = __repeat_pos;
+                    let __step_res = __parse_precedence_op(__input, __state, __err_state, __pos);
+                    match __step_res {
+                        ::peg::RuleResult::Matched(__newpos, __value) => {
+                            __repeat_pos = __newpos;
+                            __repeat_value.push(__value);
+                        }
+                        ::peg::RuleResult::Failed => {
+                            break;
+                        }
+                    }
+                }
+                if __repeat_value.len() >= 1 {
+                    ::peg::RuleResult::Matched(__repeat_pos, __repeat_value)
+                } else {
+                    ::peg::RuleResult::Failed
+                }
+            };
+            match __seq_res {
+                ::peg::RuleResult::Matched(__pos, operators) => ::peg::RuleResult::Matched(
+                    __pos,
+                    (|| PrecedenceLevel {
+                        operators: operators,
+                    })(),
+                ),
+                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+            }
+        }
+    }
+    fn __parse_precedence_op<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<PrecedenceOperator> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __seq_res = __parse_sp(__input, __state, __err_state, __pos);
+            match __seq_res {
+                ::peg::RuleResult::Matched(__pos, span) => {
+                    let __seq_res = {
+                        let mut __repeat_pos = __pos;
+                        let mut __repeat_value = vec![];
+                        loop {
+                            let __pos = __repeat_pos;
+                            let __step_res = __parse_labeled(__input, __state, __err_state, __pos);
+                            match __step_res {
+                                ::peg::RuleResult::Matched(__newpos, __value) => {
+                                    __repeat_pos = __newpos;
+                                    __repeat_value.push(__value);
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    break;
+                                }
+                            }
+                        }
+                        ::peg::RuleResult::Matched(__repeat_pos, __repeat_value)
+                    };
+                    match __seq_res {
+                        ::peg::RuleResult::Matched(__pos, elements) => {
+                            let __seq_res =
+                                __parse_BRACE_GROUP(__input, __state, __err_state, __pos);
+                            match __seq_res {
+                                ::peg::RuleResult::Matched(__pos, action) => {
+                                    ::peg::RuleResult::Matched(
+                                        __pos,
+                                        (|| PrecedenceOperator {
+                                            span,
+                                            elements,
+                                            action,
+                                        })(),
+                                    )
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                            }
+                        }
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                    }
+                }
+                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+            }
+        }
+    }
+    fn __parse_sp<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<Span> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        __input.next_span(__pos)
+    }
+    fn __parse_KEYWORD<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<()> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __choice_res =
+                match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "pub") {
+                    ::peg::RuleResult::Matched(__pos, __val) => {
+                        ::peg::RuleResult::Matched(__pos, __val)
+                    }
+                    ::peg::RuleResult::Failed => {
+                        __err_state.mark_failure(__pos, "\"pub\"");
+                        ::peg::RuleResult::Failed
+                    }
+                };
+            match __choice_res {
+                ::peg::RuleResult::Matched(__pos, __value) => {
+                    ::peg::RuleResult::Matched(__pos, __value)
+                }
+                ::peg::RuleResult::Failed => {
+                    let __choice_res =
+                        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "crate") {
+                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                ::peg::RuleResult::Matched(__pos, __val)
+                            }
+                            ::peg::RuleResult::Failed => {
+                                __err_state.mark_failure(__pos, "\"crate\"");
+                                ::peg::RuleResult::Failed
+                            }
+                        };
+                    match __choice_res {
+                        ::peg::RuleResult::Matched(__pos, __value) => {
+                            ::peg::RuleResult::Matched(__pos, __value)
+                        }
+                        ::peg::RuleResult::Failed => {
+                            let __choice_res = match ::peg::ParseLiteral::parse_string_literal(
+                                __input, __pos, "rule",
+                            ) {
+                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                    ::peg::RuleResult::Matched(__pos, __val)
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    __err_state.mark_failure(__pos, "\"rule\"");
+                                    ::peg::RuleResult::Failed
+                                }
+                            };
+                            match __choice_res {
+                                ::peg::RuleResult::Matched(__pos, __value) => {
+                                    ::peg::RuleResult::Matched(__pos, __value)
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    let __choice_res =
+                                        match ::peg::ParseLiteral::parse_string_literal(
+                                            __input, __pos, "use",
+                                        ) {
+                                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                                ::peg::RuleResult::Matched(__pos, __val)
+                                            }
+                                            ::peg::RuleResult::Failed => {
+                                                __err_state.mark_failure(__pos, "\"use\"");
+                                                ::peg::RuleResult::Failed
+                                            }
+                                        };
+                                    match __choice_res {
+                                        ::peg::RuleResult::Matched(__pos, __value) => {
+                                            ::peg::RuleResult::Matched(__pos, __value)
+                                        }
+                                        ::peg::RuleResult::Failed => {
+                                            match ::peg::ParseLiteral::parse_string_literal(
+                                                __input, __pos, "type",
+                                            ) {
+                                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                                    ::peg::RuleResult::Matched(__pos, __val)
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    __err_state.mark_failure(__pos, "\"type\"");
+                                                    ::peg::RuleResult::Failed
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    fn __parse_IDENT<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<Ident> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        {
+            let __seq_res = {
+                __err_state.suppress_fail += 1;
+                let __assert_res = match __parse_KEYWORD(__input, __state, __err_state, __pos) {
+                    ::peg::RuleResult::Matched(pos, _) => ::peg::RuleResult::Matched(pos, ()),
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                };
+                __err_state.suppress_fail -= 1;
+                match __assert_res {
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Matched(__pos, ()),
+                    ::peg::RuleResult::Matched(..) => ::peg::RuleResult::Failed,
+                }
+            };
+            match __seq_res {
+                ::peg::RuleResult::Matched(__pos, _) => {
+                    let __seq_res = __input.ident(__pos);
+                    match __seq_res {
+                        ::peg::RuleResult::Matched(__pos, i) => {
+                            ::peg::RuleResult::Matched(__pos, (|| i)())
+                        }
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                    }
+                }
+                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+            }
+        }
+    }
+    fn __parse_LITERAL<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<Literal> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        __input.literal(__pos)
+    }
+    fn __parse_PAREN_GROUP<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<Group> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        __input.group(__pos, Delimiter::Parenthesis)
+    }
+    fn __parse_BRACE_GROUP<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<Group> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        __input.group(__pos, Delimiter::Brace)
+    }
+    fn __parse_BRACKET_GROUP<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<Group> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        __input.group(__pos, Delimiter::Bracket)
+    }
+    fn __parse_LIFETIME<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<()> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "'") {
+            ::peg::RuleResult::Matched(__pos, __val) => {
+                let __seq_res = match __parse_IDENT(__input, __state, __err_state, __pos) {
+                    ::peg::RuleResult::Matched(pos, _) => ::peg::RuleResult::Matched(pos, ()),
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                };
+                match __seq_res {
+                    ::peg::RuleResult::Matched(__pos, _) => ::peg::RuleResult::Matched(__pos, ()),
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                }
+            }
+            ::peg::RuleResult::Failed => {
+                __err_state.mark_failure(__pos, "\"'\"");
+                ::peg::RuleResult::Failed
+            }
+        }
+    }
+    fn __parse_INTEGER<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<()> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        match __parse_LITERAL(__input, __state, __err_state, __pos) {
+            ::peg::RuleResult::Matched(pos, _) => ::peg::RuleResult::Matched(pos, ()),
+            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+        }
+    }
+}
diff --git a/grammar.rustpeg b/grammar.rustpeg
new file mode 100644 (file)
index 0000000..9e55c90
--- /dev/null
@@ -0,0 +1,159 @@
+pub grammar peg() for FlatTokenStream {
+
+use crate::ast::*;
+use crate::ast::Expr::*;
+use crate::tokens::FlatTokenStream;
+use proc_macro2::{ TokenStream, Ident, Group, Literal, Delimiter, Span };
+
+pub rule peg_grammar() -> Grammar
+    = doc:rust_doc_comment() visibility:rust_visibility() "grammar" name:IDENT() lifetime_params:rust_lifetime_params()? args:grammar_args() "for" input_type:$(rust_type()) "{" items:item()* "}"
+        { Grammar { doc, visibility, name, lifetime_params, args, input_type, items } }
+
+    rule rust_lifetime_params() -> Vec<TokenStream>
+        = "<" p:(($(LIFETIME())) ++ ",") ">" { p }
+
+rule grammar_args() -> Vec<(Ident, TokenStream)>
+    = "(" args:((i:IDENT() ":" t:$(rust_type()) { (i, t) })**",") ","? ")" { args }
+
+rule peg_rule() -> Rule
+    = doc:rust_doc_comment() cache:cacheflag() no_eof:no_eof_flag() visibility:rust_visibility()
+      span:sp() "rule"
+      header:(
+          &("_" / "__" / "___") name:IDENT() ("(" ")")? { (name, None, Vec::new()) }
+        / name:IDENT() ty_params:rust_ty_params()? params:rule_params() { (name, ty_params, params) }
+      )
+      ret_type:("->" t:$(rust_type()) {t})?
+      "=" expr:expression() ";"?
+        { Rule { span, doc, name:header.0, ty_params:header.1, params:header.2, expr, ret_type, visibility, no_eof, cache } }
+
+    rule cacheflag() -> Option<Cache> = "#" "[" "cache" "]" {Some(Cache::Simple)} / "#" "[" "cache_left_rec" "]" {Some(Cache::Recursive)} / {None}
+
+    rule no_eof_flag() -> bool = "#" "[" "no_eof" "]" {true} / {false}
+
+    rule rule_param_ty() -> RuleParamTy
+        = "rule" "<" r:$(rust_type()) ">" { RuleParamTy::Rule(r) }
+        / t:$(rust_type()) { RuleParamTy::Rust(t) }
+
+    rule rule_params() -> Vec<RuleParam>
+        = "(" params:(name:IDENT() ":" ty:rule_param_ty() { RuleParam { name, ty} }) ** "," ")" { params }
+
+rule item() -> Item
+    = u:rust_use()     { Item::Use(u) }
+    / r:peg_rule()     { Item::Rule(r) }
+
+rule rust_doc_comment() -> Option<TokenStream> = $(("#" "[" "doc" "=" LITERAL() "]")*)?
+
+rule rust_visibility() -> Option<TokenStream> = $("pub" PAREN_GROUP()? / "crate")?
+
+rule rust_use() -> TokenStream
+    = v:$("use" rust_path() (
+        "::" "*"
+        / "::" "{" ((IDENT() ("as" IDENT())?) ++ ",") "}"
+        / ("as" IDENT())?
+    ) ";") { v.to_owned() }
+
+rule rust_path()
+    = ("crate" "::")? IDENT() ++ "::"
+
+rule rust_type()
+    = BRACKET_GROUP()
+    / "&" LIFETIME()? "mut"? rust_type()
+    / "dyn" rust_type()
+    / "impl" rust_type()
+    / "(" rust_type() ** "," ")"
+    / rust_ty_path()
+
+rule rust_ty_path()
+    = "::"? (IDENT() ("::"? "<" (LIFETIME() / rust_type() / BRACE_GROUP() / LITERAL()) ++ "," ">")?) ++ "::"
+
+rule rust_ty_params() -> Vec<TokenStream>
+    = "<" p:($(rust_generic_param()) ++ ",") ">" { p }
+
+rule rust_generic_param()
+    = LIFETIME() (":" LIFETIME() ++ "+")?
+    / IDENT() (":"(LIFETIME() / "?"? rust_ty_path()) ++ "+")?
+
+rule expression() -> SpannedExpr = choice()
+
+rule choice() -> SpannedExpr = sp:sp() s:sequence() ++ "/" {
+    if s.len() == 1 {
+        s.into_iter().next().unwrap()
+    } else {
+        ChoiceExpr(s).at(sp)
+    }
+}
+
+rule sequence() -> SpannedExpr
+    = sp:sp() elements:labeled()* code:BRACE_GROUP()? {
+        if let Some(code) = code {
+            ActionExpr(elements, Some(code)).at(sp)
+        } else if elements.len() != 1 {
+            ActionExpr(elements, None).at(sp)
+        } else {
+            elements.into_iter().next().unwrap().expr
+        }
+    }
+
+rule labeled() -> TaggedExpr
+    = label:(l:IDENT() ":" {l})? expression:suffixed()
+        { TaggedExpr{ name: label, expr: expression } }
+
+rule suffixed() -> SpannedExpr
+    = e:prefixed() sp:sp() "?" { OptionalExpr(Box::new(e)).at(sp) }
+    / e:prefixed() sp:sp() "**" count:repeatcount() sep:primary() { Repeat { inner: Box::new(e), bound: count, sep: Some(Box::new(sep)) }.at(sp) }
+    / e:prefixed() sp:sp() "++" sep:primary() { Repeat { inner: Box::new(e), bound: BoundedRepeat::Plus, sep: Some(Box::new(sep)) }.at(sp )}
+    / e:prefixed() sp:sp() "*" count:repeatcount() { Repeat { inner: Box::new(e), bound: count, sep: None }.at(sp) }
+    / e:prefixed() sp:sp() "+" { Repeat { inner: Box::new(e), bound: BoundedRepeat::Plus, sep: None }.at(sp) }
+    / prefixed()
+
+rule repeatcount() -> BoundedRepeat
+    = "<" n:repeatnum() ">" { BoundedRepeat::Exact(n) }
+    / "<" min:repeatnum()? "," max:repeatnum()? ">" { BoundedRepeat::Both(min, max) }
+    / { BoundedRepeat::None }
+
+rule repeatnum() -> TokenStream = $(INTEGER() / BRACE_GROUP())
+
+rule prefixed() -> SpannedExpr
+    = sp:sp() "$" expression:primary() { MatchStrExpr(Box::new(expression)).at(sp) }
+    / sp:sp() "&" expression:primary() { PosAssertExpr(Box::new(expression)).at(sp) }
+    / sp:sp() "!" expression:primary() { NegAssertExpr(Box::new(expression)).at(sp) }
+    / primary()
+
+#[cache]
+rule primary() -> SpannedExpr
+  = sp:sp() "precedence" "!" "{" levels:precedence_level()**"--" "}" { PrecedenceExpr{ levels:levels }.at(sp) }
+  / sp:sp() "position" "!" "(" ")" { PositionExpr.at(sp) }
+  / sp:sp() "quiet" "!" "{" e:expression() "}" { QuietExpr(Box::new(e)).at(sp) }
+  / sp:sp() "expected" "!" "(" s:LITERAL() ")" { FailExpr(s).at(sp) }
+  / &("_" / "__" / "___") sp:sp() name:IDENT() { RuleExpr(name, Vec::new()).at(sp) }
+  / sp:sp() name:IDENT() "(" args:(rule_arg() ** ",") ")" { RuleExpr(name, args).at(sp) }
+  / sp:sp() l:LITERAL() { LiteralExpr(l).at(sp) }
+  / sp:sp() p:BRACKET_GROUP() { PatternExpr(p).at(sp) }
+  / "(" sp:sp() "@" ")" { MarkerExpr(true).at(sp) }
+  / sp:sp() "@" { MarkerExpr(false).at(sp) }
+  / sp:sp() "##" method:IDENT() args:PAREN_GROUP() { MethodExpr(method, args.stream()).at(sp) }
+  / "(" expression:expression() ")" { expression }
+
+    rule rule_arg() -> RuleArg
+        = "<" e:expression() ">" { RuleArg::Peg(e) }
+        / tt:$( ##eat_until(',')+ ) { RuleArg::Rust(tt) }
+
+rule precedence_level() -> PrecedenceLevel
+  = operators:precedence_op()+
+  { PrecedenceLevel{ operators: operators } }
+
+rule precedence_op() -> PrecedenceOperator
+  = span:sp() elements:labeled()* action:BRACE_GROUP()
+  { PrecedenceOperator{ span, elements, action } }
+
+rule sp() -> Span = ##next_span()
+rule KEYWORD() = "pub" / "crate" / "rule" / "use" / "type"
+rule IDENT() -> Ident = !KEYWORD() i:##ident() {i}
+rule LITERAL() -> Literal = ##literal()
+rule PAREN_GROUP()   -> Group = ##group(Delimiter::Parenthesis)
+rule BRACE_GROUP()   -> Group = ##group(Delimiter::Brace)
+rule BRACKET_GROUP() -> Group = ##group(Delimiter::Bracket)
+rule LIFETIME() = "'" IDENT()
+rule INTEGER() = LITERAL()
+
+}
diff --git a/lib.rs b/lib.rs
new file mode 100644 (file)
index 0000000..6393788
--- /dev/null
+++ b/lib.rs
@@ -0,0 +1,32 @@
+extern crate proc_macro;
+extern crate proc_macro2;
+extern crate quote;
+
+use quote::quote_spanned;
+
+// This can't use the `peg` crate as it would be a circular dependency, but the generated code in grammar.rs
+// requires `::peg` paths.
+extern crate peg_runtime as peg;
+
+mod analysis;
+mod ast;
+mod grammar;
+mod tokens;
+mod translate;
+
+/// The main macro for creating a PEG parser.
+///
+/// For the grammar syntax, see the `peg` crate documentation.
+#[proc_macro]
+pub fn parser(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
+    let tokens = tokens::FlatTokenStream::new(input.into());
+    let grammar = match grammar::peg::peg_grammar(&tokens) {
+        Ok(g) => g,
+        Err(err) => {
+            let msg = format!("expected {}", err.expected);
+            return quote_spanned!(err.location.0=> compile_error!(#msg);).into();
+        }
+    };
+
+    translate::compile_grammar(&grammar).into()
+}
diff --git a/tokens.rs b/tokens.rs
new file mode 100644 (file)
index 0000000..3ca6139
--- /dev/null
+++ b/tokens.rs
@@ -0,0 +1,204 @@
+use peg::{Parse, ParseElem, ParseLiteral, ParseSlice, RuleResult};
+use proc_macro2::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
+
+#[derive(Debug, Clone)]
+pub struct FlatTokenStream {
+    tokens: Vec<Token>,
+}
+
+#[derive(Debug, Clone)]
+pub enum Token {
+    Ident(Ident),
+    Literal(Literal),
+    Punct(Punct),
+    Begin(Group, usize),
+    End(Delimiter, Span),
+}
+
+impl Token {
+    fn span(&self) -> Span {
+        match self {
+            Token::Ident(i) => i.span(),
+            Token::Literal(l) => l.span(),
+            Token::Punct(p) => p.span(),
+            Token::Begin(g, _) => g.span(),
+            Token::End(_, span) => span.clone(),
+        }
+    }
+}
+
+impl FlatTokenStream {
+    pub fn new(stream: TokenStream) -> FlatTokenStream {
+        let mut tokens = vec![];
+
+        fn flatten(tokens: &mut Vec<Token>, tree: TokenTree) {
+            match tree {
+                TokenTree::Ident(i) => tokens.push(Token::Ident(i)),
+                TokenTree::Literal(l) => tokens.push(Token::Literal(l)),
+                TokenTree::Punct(p) => tokens.push(Token::Punct(p)),
+                TokenTree::Group(g) => {
+                    let start_pos = tokens.len();
+
+                    tokens.push(Token::End(g.delimiter(), g.span())); // placeholder
+                    for tree in g.stream() {
+                        flatten(tokens, tree);
+                    }
+                    tokens.push(Token::End(g.delimiter(), g.span()));
+
+                    let end_pos = tokens.len();
+                    tokens[start_pos] = Token::Begin(g, end_pos);
+                }
+            }
+        }
+
+        for tree in stream {
+            flatten(&mut tokens, tree);
+        }
+
+        FlatTokenStream { tokens }
+    }
+
+    pub fn next_span(&self, pos: usize) -> RuleResult<Span> {
+        match self.tokens.get(pos) {
+            Some(t) => RuleResult::Matched(pos, t.span()),
+            _ => RuleResult::Failed,
+        }
+    }
+
+    pub fn ident(&self, pos: usize) -> RuleResult<Ident> {
+        match self.tokens.get(pos) {
+            Some(Token::Ident(i)) => RuleResult::Matched(pos + 1, i.clone()),
+            _ => RuleResult::Failed,
+        }
+    }
+
+    pub fn literal(&self, pos: usize) -> RuleResult<Literal> {
+        match self.tokens.get(pos) {
+            Some(Token::Literal(i)) => RuleResult::Matched(pos + 1, i.clone()),
+            _ => RuleResult::Failed,
+        }
+    }
+
+    pub fn group(&self, pos: usize, delim: Delimiter) -> RuleResult<Group> {
+        match self.tokens.get(pos) {
+            Some(Token::Begin(g, n)) if g.delimiter() == delim => {
+                RuleResult::Matched(*n, g.clone())
+            }
+            _ => RuleResult::Failed,
+        }
+    }
+
+    pub fn eat_until(&self, initial_pos: usize, end: char) -> RuleResult<()> {
+        let mut pos = initial_pos;
+        loop {
+            match self.tokens.get(pos) {
+                Some(Token::Begin(_, n)) => pos = *n,
+                Some(Token::Ident(_)) | Some(Token::Literal(_)) => pos += 1,
+                Some(Token::Punct(p)) if p.as_char() != end => pos += 1,
+                _ if pos != initial_pos => return RuleResult::Matched(pos, ()),
+                _ => return RuleResult::Failed,
+            }
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct Sp(pub Span, pub usize);
+
+impl ::std::fmt::Display for Sp {
+    fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
+        write!(fmt, "{:?} ({})", self.0, self.1)
+    }
+}
+
+impl Parse for FlatTokenStream {
+    type PositionRepr = Sp;
+    fn start(&self) -> usize {
+        0
+    }
+
+    fn is_eof(&self, pos: usize) -> bool {
+        pos >= self.tokens.len()
+    }
+
+    fn position_repr(&self, pos: usize) -> Sp {
+        Sp(self.tokens[pos].span(), pos)
+    }
+}
+
+impl<'input> ParseElem<'input> for FlatTokenStream {
+    type Element = &'input Token;
+
+    fn parse_elem(&'input self, pos: usize) -> RuleResult<&'input Token> {
+        match self.tokens.get(pos) {
+            Some(c) => RuleResult::Matched(pos + 1, c),
+            None => RuleResult::Failed,
+        }
+    }
+}
+
+fn delimiter_start(d: Delimiter) -> &'static str {
+    match d {
+        Delimiter::Brace => "{",
+        Delimiter::Bracket => "[",
+        Delimiter::Parenthesis => "(",
+        _ => "",
+    }
+}
+
+fn delimiter_end(d: Delimiter) -> &'static str {
+    match d {
+        Delimiter::Brace => "}",
+        Delimiter::Bracket => "]",
+        Delimiter::Parenthesis => ")",
+        _ => "",
+    }
+}
+
+impl ParseLiteral for FlatTokenStream {
+    fn parse_string_literal(&self, pos: usize, literal: &str) -> RuleResult<()> {
+        match self.tokens.get(pos) {
+            Some(Token::Ident(i)) if i.to_string() == literal => RuleResult::Matched(pos + 1, ()),
+            Some(Token::Punct(p)) if literal.starts_with(p.as_char()) => {
+                if literal.len() == 1 {
+                    RuleResult::Matched(pos + 1, ())
+                } else if p.spacing() == Spacing::Joint {
+                    self.parse_string_literal(pos + 1, &literal[1..])
+                } else {
+                    RuleResult::Failed
+                }
+            }
+            Some(Token::Begin(g, _)) if delimiter_start(g.delimiter()) == literal => {
+                RuleResult::Matched(pos + 1, ())
+            }
+            Some(Token::End(d, _)) if delimiter_end(*d) == literal => {
+                RuleResult::Matched(pos + 1, ())
+            }
+            _ => RuleResult::Failed,
+        }
+    }
+}
+
+impl<'input> ParseSlice<'input> for FlatTokenStream {
+    type Slice = TokenStream;
+    fn parse_slice(&'input self, p1: usize, p2: usize) -> TokenStream {
+        let mut ts = TokenStream::new();
+        let mut pos = p1;
+
+        while pos < p2 {
+            let (t, next_pos): (TokenTree, usize) = match &self.tokens[pos] {
+                Token::Ident(i) => (i.clone().into(), pos + 1),
+                Token::Literal(l) => (l.clone().into(), pos + 1),
+                Token::Punct(p) => (p.clone().into(), pos + 1),
+                Token::Begin(g, end) => (g.clone().into(), *end),
+                Token::End(..) => panic!("$-expr containing unmatched group end"),
+            };
+            ts.extend(Some(t));
+            pos = next_pos;
+        }
+
+        assert_eq!(pos, p2, "$-expr containing unmatched group start");
+
+        ts
+    }
+}
diff --git a/translate.rs b/translate.rs
new file mode 100644 (file)
index 0000000..691fbf7
--- /dev/null
@@ -0,0 +1,1001 @@
+use proc_macro2::{Group, Ident, Literal, Span, TokenStream, TokenTree};
+use std::collections::{HashMap, HashSet};
+
+use quote::{format_ident, quote, quote_spanned};
+
+pub use self::Expr::*;
+use crate::analysis;
+use crate::ast::*;
+
+pub fn report_error(span: Span, msg: String) -> TokenStream {
+    quote_spanned!(span=>compile_error!(#msg);)
+}
+
+pub fn report_error_expr(span: Span, msg: String) -> TokenStream {
+    // panic!() to avoid "Mismatched types" error
+    quote_spanned!(span=> { compile_error!(#msg); panic!() })
+}
+
+/// Test if the group begins with a specific marker character, and if so, return the remaining tokens.
+fn group_check_prefix(group: &Group, prefix: char) -> Option<TokenStream> {
+    let mut iter = group.stream().into_iter();
+    match iter.next() {
+        Some(TokenTree::Punct(p)) if p.as_char() == prefix => Some(iter.collect()),
+        _ => None,
+    }
+}
+
+fn extra_args_def(grammar: &Grammar) -> TokenStream {
+    let args: Vec<TokenStream> = grammar
+        .args
+        .iter()
+        .map(|&(ref name, ref tp)| quote!(, #name: #tp))
+        .collect();
+    quote!(#(#args)*)
+}
+
+fn extra_args_call(grammar: &Grammar) -> TokenStream {
+    let args: Vec<TokenStream> = grammar
+        .args
+        .iter()
+        .map(|&(ref name, _)| quote!(, #name))
+        .collect();
+    quote!(#(#args)*)
+}
+
+#[derive(Clone)]
+struct Context<'a> {
+    rules: &'a HashMap<String, &'a Rule>,
+    rules_from_args: HashSet<String>,
+    grammar_lifetime_params: &'a [TokenStream],
+    input_ty: TokenStream,
+    parse_state_ty: TokenStream,
+    extra_args_call: TokenStream,
+    extra_args_def: TokenStream,
+}
+
+pub(crate) fn compile_grammar(grammar: &Grammar) -> TokenStream {
+    let analysis = analysis::check(grammar);
+
+    let grammar_lifetime_params = ty_params_slice(&grammar.lifetime_params);
+
+    let context = &Context {
+        rules: &analysis.rules,
+        rules_from_args: HashSet::new(),
+        grammar_lifetime_params,
+        input_ty: quote!(&'input Input<#(#grammar_lifetime_params),*>),
+        parse_state_ty: quote!(&mut ParseState<'input #(, #grammar_lifetime_params)*>),
+        extra_args_call: extra_args_call(grammar),
+        extra_args_def: extra_args_def(grammar),
+    };
+
+    let mut seen_rule_names = HashSet::new();
+
+    let mut items = vec![];
+    for item in &grammar.items {
+        match item {
+            Item::Use(tt) => items.push(tt.clone()),
+            Item::Rule(rule) => {
+                if !seen_rule_names.insert(rule.name.to_string()) {
+                    items.push(report_error(
+                        rule.name.span(),
+                        format!("duplicate rule `{}`", rule.name),
+                    ));
+                    continue;
+                }
+
+                if rule.cache.is_some() && !(rule.params.is_empty() && rule.ty_params.is_none()) {
+                    items.push(report_error(
+                            rule.name.span(),
+                            "rules with generics or parameters cannot use #[cache] or #[cache_left_rec]".to_string(),
+                    ));
+                    continue;
+                }
+
+                if rule.visibility.is_some() {
+                    for param in &rule.params {
+                        if let RuleParamTy::Rule(..) = &param.ty {
+                            items.push(report_error(
+                                param.name.span(),
+                                "parameters on `pub rule` must be Rust types".to_string(),
+                            ))
+                        }
+                    }
+
+                    items.push(compile_rule_export(context, rule));
+                } else if rule.no_eof {
+                    items.push(report_error(
+                        rule.name.span(),
+                        "#[no_eof] is only meaningful for `pub rule`".to_string(),
+                    ));
+                }
+
+                items.push(compile_rule(context, rule));
+            }
+        }
+    }
+
+    let parse_state = make_parse_state(grammar);
+    let Grammar {
+        name,
+        doc,
+        input_type,
+        visibility,
+        ..
+    } = grammar;
+
+    let mut errors: Vec<TokenStream> = analysis
+        .left_recursion
+        .iter()
+        .map(|rec| report_error(rec.span, rec.msg()))
+        .collect();
+
+    errors.extend(
+        analysis
+            .loop_nullability
+            .iter()
+            .map(|nl| report_error(nl.span, nl.msg())),
+    );
+
+    quote_spanned! { Span::mixed_site() =>
+        #doc
+        #visibility mod #name {
+            #[allow(unused_imports)]
+            use super::*;
+            type Input<#(#grammar_lifetime_params),*> = #input_type;
+            type PositionRepr<#(#grammar_lifetime_params),*> = <Input<#(#grammar_lifetime_params),*> as ::peg::Parse>::PositionRepr;
+
+            #(#errors)*
+            #parse_state
+            #(#items)*
+        }
+    }
+}
+
+fn make_parse_state(grammar: &Grammar) -> TokenStream {
+    let span = Span::mixed_site();
+    let grammar_lifetime_params = ty_params_slice(&grammar.lifetime_params);
+    let mut cache_fields_def: Vec<TokenStream> = Vec::new();
+    let mut cache_fields: Vec<Ident> = Vec::new();
+    for rule in grammar.iter_rules() {
+        if rule.cache.is_some() && rule.params.is_empty() && rule.ty_params.is_none() {
+            let name = format_ident!("{}_cache", rule.name);
+            let ret_ty = rule.ret_type.clone().unwrap_or_else(|| quote!(()));
+            cache_fields_def.push(
+                quote_spanned! { span =>  #name: ::std::collections::HashMap<usize, ::peg::RuleResult<#ret_ty>> },
+            );
+            cache_fields.push(name);
+        }
+    }
+
+    quote_spanned! { span =>
+        #[allow(unused_parens)]
+        struct ParseState<'input #(, #grammar_lifetime_params)*> {
+            _phantom: ::std::marker::PhantomData<(&'input () #(, &#grammar_lifetime_params ())*)>,
+            #(#cache_fields_def),*
+        }
+
+        impl<'input #(, #grammar_lifetime_params)*> ParseState<'input #(, #grammar_lifetime_params)*> {
+            fn new() -> ParseState<'input #(, #grammar_lifetime_params)*> {
+                ParseState {
+                    _phantom: ::std::marker::PhantomData,
+                    #(#cache_fields: ::std::collections::HashMap::new()),*
+                }
+            }
+        }
+    }
+}
+
+fn ty_params_slice(ty_params: &Option<Vec<TokenStream>>) -> &[TokenStream] {
+    ty_params.as_ref().map(|x| &x[..]).unwrap_or(&[])
+}
+
+fn rule_params_list(context: &Context, rule: &Rule) -> Vec<TokenStream> {
+    let Context {
+        input_ty,
+        parse_state_ty,
+        ..
+    } = context;
+    let span = rule.span.resolved_at(Span::mixed_site());
+    rule.params.iter().map(|param| {
+        let name = &param.name;
+        match &param.ty {
+            RuleParamTy::Rust(ty) => quote_spanned!{ span => #name: #ty },
+            RuleParamTy::Rule(ty) => quote_spanned!{ span =>
+                #name: impl Fn(#input_ty, #parse_state_ty, &mut ::peg::error::ErrorState, usize) -> ::peg::RuleResult<#ty>
+            },
+        }
+    }).collect()
+}
+
+/// Compile a rule to a function for use internal to the grammar.
+/// Returns `RuleResult<T>`.
+fn compile_rule(context: &Context, rule: &Rule) -> TokenStream {
+    let span = rule.span.resolved_at(Span::mixed_site());
+    let name = format_ident!("__parse_{}", rule.name, span = span);
+    let ret_ty = rule.ret_type.clone().unwrap_or_else(|| quote!(()));
+    let ty_params = ty_params_slice(&rule.ty_params);
+
+    let Context {
+        input_ty,
+        parse_state_ty,
+        grammar_lifetime_params,
+        extra_args_def,
+        ..
+    } = context;
+
+    let mut context = context.clone();
+    context
+        .rules_from_args
+        .extend(rule.params.iter().map(|param| param.name.to_string()));
+
+    let body = compile_expr(&context, &rule.expr, rule.ret_type.is_some());
+
+    let wrapped_body = if cfg!(feature = "trace") {
+        let str_rule_name = rule.name.to_string();
+        quote_spanned! { span => {
+            let loc = ::peg::Parse::position_repr(__input, __pos);
+            println!("[PEG_TRACE] Attempting to match rule `{}` at {}", #str_rule_name, loc);
+            let __peg_result: ::peg::RuleResult<#ret_ty> = {#body};
+            match __peg_result {
+                ::peg::RuleResult::Matched(epos, _) => {
+                    let eloc = ::peg::Parse::position_repr(__input, epos);
+                    println!("[PEG_TRACE] Matched rule `{}` at {} to {}", #str_rule_name, loc, eloc);
+                }
+                ::peg::RuleResult::Failed => {
+                    println!("[PEG_TRACE] Failed to match rule `{}` at {}", #str_rule_name, loc);
+                }
+            }
+
+            __peg_result
+        }}
+    } else {
+        body
+    };
+
+    let rule_params = rule_params_list(&context, rule);
+
+    let fn_body = match &rule.cache {
+        None => wrapped_body,
+        Some(cache_type) => {
+            let cache_field = format_ident!("{}_cache", rule.name);
+
+            let cache_trace = if cfg!(feature = "trace") {
+                let str_rule_name = rule.name.to_string();
+                quote_spanned! { span =>
+                    let loc = ::peg::Parse::position_repr(__input, __pos);
+                    match &entry {
+                        &::peg::RuleResult::Matched(..) => println!("[PEG_TRACE] Cached match of rule {} at {}", #str_rule_name, loc),
+                        &Failed => println!("[PEG_TRACE] Cached fail of rule {} at {}", #str_rule_name, loc),
+                    };
+                }
+            } else {
+                quote!()
+            };
+
+            match cache_type {
+                Cache::Simple => quote_spanned! { span =>
+                    if let Some(entry) = __state.#cache_field.get(&__pos) {
+                        #cache_trace
+                        return entry.clone();
+                    }
+
+                    let __rule_result = #wrapped_body;
+                    __state.#cache_field.insert(__pos, __rule_result.clone());
+                    __rule_result
+                },
+                Cache::Recursive =>
+                // `#[cache_left_rec] support for recursive rules using the technique described here:
+                // <https://medium.com/@gvanrossum_83706/left-recursive-peg-grammars-65dab3c580e1>
+                {
+                    quote_spanned! { span =>
+                        if let Some(entry) = __state.#cache_field.get(&__pos) {
+                            #cache_trace
+                            return entry.clone();
+                        }
+
+                        __state.#cache_field.insert(__pos, ::peg::RuleResult::Failed);
+                        let mut __last_result = ::peg::RuleResult::Failed;
+                        loop {
+                            let __current_result = { #wrapped_body };
+                            match __current_result {
+                                ::peg::RuleResult::Failed => break,
+                                ::peg::RuleResult::Matched(__current_endpos, _) =>
+                                    match __last_result {
+                                        ::peg::RuleResult::Matched(__last_endpos, _) if __current_endpos <= __last_endpos => break,
+                                        _ => {
+                                            __state.#cache_field.insert(__pos, __current_result.clone());
+                                            __last_result = __current_result;
+                                        },
+                                    }
+                            }
+                        }
+
+                        return __last_result;
+                    }
+                }
+            }
+        }
+    };
+
+    quote_spanned! { span =>
+        fn #name<'input #(, #grammar_lifetime_params)* #(, #ty_params)*>(__input: #input_ty, __state: #parse_state_ty, __err_state: &mut ::peg::error::ErrorState, __pos: usize #extra_args_def #(, #rule_params)*) -> ::peg::RuleResult<#ret_ty> {
+            #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+            #fn_body
+        }
+    }
+}
+
+/// Compile a rule into the parsing function which will be exported.
+/// Returns `Result<T, ParseError>`.
+fn compile_rule_export(context: &Context, rule: &Rule) -> TokenStream {
+    let span = rule.span.resolved_at(Span::mixed_site());
+
+    let Rule {
+        doc,
+        name,
+        visibility,
+        ..
+    } = rule;
+    let ret_ty = rule.ret_type.clone().unwrap_or_else(|| quote!(()));
+    let parse_fn = format_ident!("__parse_{}", rule.name.to_string(), span = name.span());
+    let ty_params = ty_params_slice(&rule.ty_params);
+    let rule_params = rule_params_list(context, rule);
+    let rule_params_call: Vec<TokenStream> = rule
+        .params
+        .iter()
+        .map(|param| {
+            let param_name = &param.name;
+            quote!(#param_name)
+        })
+        .collect();
+
+    let Context {
+        input_ty,
+        extra_args_call,
+        extra_args_def,
+        grammar_lifetime_params,
+        ..
+    } = context;
+    let eof_check = if rule.no_eof {
+        quote_spanned! { span => true }
+    } else {
+        quote_spanned! { span => ::peg::Parse::is_eof(__input, __pos) }
+    };
+
+    // Parse once. If it succeeds or throws an error, return that.
+    // If it fails, parse again to determine the set of all tokens
+    // that were expected at the failure position.
+
+    quote_spanned! { span =>
+        #doc
+        #visibility fn #name<'input #(, #grammar_lifetime_params)* #(, #ty_params)*>(__input: #input_ty #extra_args_def #(, #rule_params)*) -> ::std::result::Result<#ret_ty, ::peg::error::ParseError<PositionRepr<#(#grammar_lifetime_params),*>>> {
+            #![allow(non_snake_case, unused)]
+
+            let mut __err_state = ::peg::error::ErrorState::new(::peg::Parse::start(__input));
+            let mut __state = ParseState::new();
+            match #parse_fn(__input, &mut __state, &mut __err_state, ::peg::Parse::start(__input) #extra_args_call #(, #rule_params_call)*) {
+                ::peg::RuleResult::Matched(__pos, __value) => {
+                    if #eof_check {
+                        return Ok(__value)
+                    } else {
+                        __err_state.mark_failure(__pos, "EOF");
+                    }
+                }
+                _ => ()
+            }
+
+            __state = ParseState::new();
+            __err_state.reparse_for_error();
+
+            match #parse_fn(__input, &mut __state, &mut __err_state, ::peg::Parse::start(__input) #extra_args_call #(, #rule_params_call)*) {
+                ::peg::RuleResult::<#ret_ty>::Matched(__pos, __value) => {
+                    if #eof_check {
+                        panic!("Parser is nondeterministic: succeeded when reparsing for error position");
+                    } else {
+                        __err_state.mark_failure(__pos, "EOF");
+                    }
+                }
+                _ => ()
+            }
+
+            Err(__err_state.into_parse_error(__input))
+        }
+    }
+}
+
+fn name_or_ignore(n: Option<&Ident>) -> TokenStream {
+    match n {
+        Some(n) => quote!(#n),
+        None => quote!(_),
+    }
+}
+
+fn ordered_choice(span: Span, mut rs: impl DoubleEndedIterator<Item = TokenStream>) -> TokenStream {
+    rs.next_back().map(|last| rs.rfold(last, |fallback, preferred| {
+        quote_spanned! { span => {
+            let __choice_res = #preferred;
+            match __choice_res {
+                ::peg::RuleResult::Matched(__pos, __value) => ::peg::RuleResult::Matched(__pos, __value),
+                ::peg::RuleResult::Failed => #fallback
+            }
+        }}
+    })).expect("ordered choice must not be empty")
+}
+
+fn labeled_seq(context: &Context, exprs: &[TaggedExpr], inner: TokenStream) -> TokenStream {
+    exprs.iter().rfold(inner, |then, expr| {
+        compile_expr_continuation(context, &expr.expr, expr.name.as_ref(), then)
+    })
+}
+
+fn compile_expr_continuation(
+    context: &Context,
+    e: &SpannedExpr,
+    result_name: Option<&Ident>,
+    continuation: TokenStream,
+) -> TokenStream {
+    let span = e.span.resolved_at(Span::mixed_site());
+
+    let result_pat = name_or_ignore(result_name);
+    match e.expr {
+        LiteralExpr(ref s) => compile_literal_expr(s, continuation),
+
+        PatternExpr(ref pattern) => {
+            let result_name = result_name
+                .cloned()
+                .unwrap_or_else(|| Ident::new("__ch", span));
+            compile_pattern_expr(
+                pattern,
+                result_name,
+                quote_spanned! { span =>
+                    { let __pos = __next; { #continuation } }
+                },
+            )
+        }
+
+        _ => {
+            let seq_res = compile_expr(context, e, result_name.is_some());
+            quote_spanned! { span => {
+                let __seq_res = #seq_res;
+                match __seq_res {
+                    ::peg::RuleResult::Matched(__pos, #result_pat) => { #continuation }
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                }
+            }}
+        }
+    }
+}
+
+fn compile_literal_expr(s: &Literal, continuation: TokenStream) -> TokenStream {
+    let span = s.span().resolved_at(Span::mixed_site());
+    let escaped_str = s.to_string();
+    quote_spanned! { span =>
+            match ::peg::ParseLiteral::parse_string_literal(__input, __pos, #s) {
+            ::peg::RuleResult::Matched(__pos, __val) => { #continuation }
+            ::peg::RuleResult::Failed => { __err_state.mark_failure(__pos, #escaped_str); ::peg::RuleResult::Failed }
+        }
+    }
+}
+
+fn compile_pattern_expr(
+    pattern_group: &Group,
+    result_name: Ident,
+    success_res: TokenStream,
+) -> TokenStream {
+    let span = pattern_group.span().resolved_at(Span::mixed_site());
+    let pat_str = pattern_group.to_string();
+    let failure_res = quote_spanned! { span => { __err_state.mark_failure(__pos, #pat_str); ::peg::RuleResult::Failed } };
+
+    let (pattern, in_set, not_in_set) =
+        if let Some(pattern) = group_check_prefix(pattern_group, '^') {
+            (pattern, failure_res, success_res)
+        } else {
+            (pattern_group.stream(), success_res, failure_res)
+        };
+
+    quote_spanned! { span =>
+        match ::peg::ParseElem::parse_elem(__input, __pos) {
+            ::peg::RuleResult::Matched(__next, #result_name) => match #result_name {
+                #pattern => #in_set,
+                _ => #not_in_set,
+            }
+            ::peg::RuleResult::Failed => { __err_state.mark_failure(__pos, #pat_str); ::peg::RuleResult::Failed }
+        }
+    }
+}
+
+fn compile_expr(context: &Context, e: &SpannedExpr, result_used: bool) -> TokenStream {
+    let span = e.span.resolved_at(Span::mixed_site());
+
+    match e.expr {
+        LiteralExpr(ref s) => compile_literal_expr(
+            s,
+            quote_spanned! { span =>
+                 ::peg::RuleResult::Matched(__pos, __val)
+            },
+        ),
+
+        PatternExpr(ref pattern_group) => {
+            let res_name = Ident::new("__ch", span);
+            let res = if result_used {
+                quote!(#res_name)
+            } else {
+                quote_spanned! { span => () }
+            };
+            compile_pattern_expr(
+                pattern_group,
+                res_name,
+                quote_spanned! { span =>
+                    ::peg::RuleResult::Matched(__next, #res)
+                },
+            )
+        }
+
+        RuleExpr(ref rule_name, ref rule_args)
+            if context.rules_from_args.contains(&rule_name.to_string()) =>
+        {
+            if !rule_args.is_empty() {
+                return report_error_expr(
+                    rule_name.span(),
+                    "rule closure does not accept arguments".to_string(),
+                );
+            }
+
+            quote_spanned! { span=> #rule_name(__input, __state, __err_state, __pos) }
+        }
+
+        RuleExpr(ref rule_name, ref rule_args) => {
+            let rule_name_str = rule_name.to_string();
+
+            let rule_def = if let Some(rule_def) = context.rules.get(&rule_name_str) {
+                rule_def
+            } else {
+                return report_error_expr(
+                    rule_name.span(),
+                    format!("undefined rule `{}`", rule_name_str),
+                );
+            };
+
+            if result_used && rule_def.ret_type.is_none() {
+                let msg = format!(
+                    "using result of rule `{}`, which does not return a value",
+                    rule_name_str
+                );
+                return report_error_expr(rule_name.span(), msg);
+            }
+
+            if rule_def.params.len() != rule_args.len() {
+                return report_error_expr(
+                    rule_name.span(),
+                    format!(
+                        "this rule takes {} parameters but {} parameters were supplied",
+                        rule_def.params.len(),
+                        rule_args.len()
+                    ),
+                );
+            }
+
+            let func = format_ident!("__parse_{}", rule_name, span = rule_name.span());
+            let extra_args_call = &context.extra_args_call;
+
+            let rule_args_call: Vec<TokenStream> = rule_args
+                .iter()
+                .map(|arg| match arg {
+                    RuleArg::Peg(e) => {
+                        let expr = compile_expr(context, e, true);
+                        quote_spanned! { span=> |__input, __state, __err_state, __pos| { #expr } }
+                    }
+                    RuleArg::Rust(e) => e.clone(),
+                })
+                .collect();
+
+            if result_used {
+                quote_spanned! { span=> #func(__input, __state, __err_state, __pos #extra_args_call #(, #rule_args_call)*) }
+            } else {
+                quote_spanned! { span=>
+                    match #func(__input, __state, __err_state, __pos #extra_args_call #(, #rule_args_call)*){
+                        ::peg::RuleResult::Matched(pos, _) => ::peg::RuleResult::Matched(pos, ()),
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                    }
+                }
+            }
+        }
+
+        MethodExpr(ref method, ref args) => {
+            quote_spanned! { span=> __input.#method(__pos, #args) }
+        }
+
+        ChoiceExpr(ref exprs) => ordered_choice(
+            span,
+            exprs
+                .iter()
+                .map(|expr| compile_expr(context, expr, result_used)),
+        ),
+
+        OptionalExpr(ref e) => {
+            let optional_res = compile_expr(context, e, result_used);
+
+            if result_used {
+                quote_spanned! { span=>
+                    match #optional_res {
+                        ::peg::RuleResult::Matched(__newpos, __value) => { ::peg::RuleResult::Matched(__newpos, Some(__value)) },
+                        ::peg::RuleResult::Failed => { ::peg::RuleResult::Matched(__pos, None) },
+                    }
+                }
+            } else {
+                quote_spanned! { span=>
+                    match #optional_res {
+                        ::peg::RuleResult::Matched(__newpos, _) => { ::peg::RuleResult::Matched(__newpos, ()) },
+                        ::peg::RuleResult::Failed => { ::peg::RuleResult::Matched(__pos, ()) },
+                    }
+                }
+            }
+        }
+
+        Repeat {
+            ref inner,
+            ref bound,
+            ref sep,
+        } => {
+            let inner = compile_expr(context, inner, result_used);
+
+            let (min, max) = match bound {
+                BoundedRepeat::None => (None, None),
+                BoundedRepeat::Plus => (Some(quote!(1)), None),
+                BoundedRepeat::Exact(ref code) => (Some(code.clone()), Some(code.clone())),
+                BoundedRepeat::Both(ref min, ref max) => (min.clone(), max.clone()),
+            };
+
+            let match_sep = if let Some(sep) = sep {
+                let sep_inner = compile_expr(context, sep, false);
+                quote_spanned! { span=>
+                    let __pos = if __repeat_value.is_empty() { __pos } else {
+                        let __sep_res = #sep_inner;
+                        match __sep_res {
+                            ::peg::RuleResult::Matched(__newpos, _) => { __newpos },
+                            ::peg::RuleResult::Failed => break,
+                        }
+                    };
+                }
+            } else {
+                quote!()
+            };
+
+            let result = if result_used {
+                quote_spanned! { span=> __repeat_value }
+            } else {
+                quote!(())
+            };
+
+            let (repeat_vec, repeat_step) =
+                if result_used || min.is_some() || max.is_some() || sep.is_some() {
+                    (
+                        Some(quote_spanned! { span => let mut __repeat_value = vec!(); }),
+                        Some(quote_spanned! { span => __repeat_value.push(__value); }),
+                    )
+                } else {
+                    (None, None)
+                };
+
+            let max_check = max.map(|max| {
+                quote_spanned! { span=> if __repeat_value.len() >= #max { break } }
+            });
+
+            let result_check = if let Some(min) = min {
+                quote_spanned! { span=>
+                    if __repeat_value.len() >= #min {
+                        ::peg::RuleResult::Matched(__repeat_pos, #result)
+                    } else {
+                        ::peg::RuleResult::Failed
+                    }
+                }
+            } else {
+                quote_spanned! { span=> ::peg::RuleResult::Matched(__repeat_pos, #result) }
+            };
+
+            quote_spanned! { span=> {
+                let mut __repeat_pos = __pos;
+                #repeat_vec
+
+                loop {
+                    let __pos = __repeat_pos;
+
+                    #match_sep
+                    #max_check
+
+                    let __step_res = #inner;
+                    match __step_res {
+                        ::peg::RuleResult::Matched(__newpos, __value) => {
+                            __repeat_pos = __newpos;
+                            #repeat_step
+                        },
+                        ::peg::RuleResult::Failed => {
+                            break;
+                        }
+                    }
+                }
+
+                #result_check
+            }}
+        }
+
+        PosAssertExpr(ref e) => {
+            let assert_res = compile_expr(context, e, result_used);
+            quote_spanned! { span=> {
+                __err_state.suppress_fail += 1;
+                let __assert_res = #assert_res;
+                __err_state.suppress_fail -= 1;
+                match __assert_res {
+                    ::peg::RuleResult::Matched(_, __value) => ::peg::RuleResult::Matched(__pos, __value),
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                }
+            }}
+        }
+
+        NegAssertExpr(ref e) => {
+            let assert_res = compile_expr(context, e, false);
+            quote_spanned! { span=> {
+                __err_state.suppress_fail += 1;
+                let __assert_res = #assert_res;
+                __err_state.suppress_fail -= 1;
+                match __assert_res {
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Matched(__pos, ()),
+                    ::peg::RuleResult::Matched(..) => ::peg::RuleResult::Failed,
+                }
+            }}
+        }
+
+        ActionExpr(ref exprs, ref code) => labeled_seq(context, exprs, {
+            if let Some(code) = code {
+                let code_span = code.span().resolved_at(Span::mixed_site());
+
+                // Peek and see if the first token in the block is '?'. If so, it's a conditional block
+                if let Some(body) = group_check_prefix(code, '?') {
+                    quote_spanned! {code_span =>
+                        match (||{ #body })() {
+                            Ok(res) => ::peg::RuleResult::Matched(__pos, res),
+                            Err(expected) => {
+                                __err_state.mark_failure(__pos, expected);
+                                ::peg::RuleResult::Failed
+                            },
+                        }
+                    }
+                } else {
+                    quote_spanned! {code_span => ::peg::RuleResult::Matched(__pos, (||#code)()) }
+                }
+            } else {
+                quote_spanned! { span => ::peg::RuleResult::Matched(__pos, ()) }
+            }
+        }),
+        MatchStrExpr(ref expr) => {
+            let inner = compile_expr(context, expr, false);
+            quote_spanned! { span => {
+                let str_start = __pos;
+                match #inner {
+                    ::peg::RuleResult::Matched(__newpos, _) => { ::peg::RuleResult::Matched(__newpos, ::peg::ParseSlice::parse_slice(__input, str_start, __newpos)) },
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                }
+            }}
+        }
+        PositionExpr => {
+            quote_spanned! { span => ::peg::RuleResult::Matched(__pos, __pos) }
+        }
+        QuietExpr(ref expr) => {
+            let inner = compile_expr(context, expr, result_used);
+            quote_spanned! { span => {
+                __err_state.suppress_fail += 1;
+                let res = #inner;
+                __err_state.suppress_fail -= 1;
+                res
+            }}
+        }
+        FailExpr(ref expected) => {
+            quote_spanned! { span => { __err_state.mark_failure(__pos, #expected); ::peg::RuleResult::Failed }}
+        }
+
+        PrecedenceExpr { ref levels } => {
+            let mut pre_rules = Vec::new();
+            let mut level_code = Vec::new();
+            let mut span_capture: Option<(TokenStream, TokenStream, TokenStream, &Group)> = None;
+
+            for (prec, level) in levels.iter().enumerate() {
+                let prec = prec as i32;
+
+                let mut post_rules = Vec::new();
+
+                for op in &level.operators {
+                    let op_span = op.span.resolved_at(Span::mixed_site());
+
+                    if op.elements.is_empty() {
+                        return report_error(op_span, "incomplete rule".to_string());
+                    }
+
+                    let left_arg = &op.elements[0];
+                    let l_arg = name_or_ignore(left_arg.name.as_ref());
+
+                    let right_arg = &op.elements[op.elements.len() - 1];
+                    let r_arg = name_or_ignore(right_arg.name.as_ref());
+
+                    let action = &op.action;
+                    let action = quote_spanned!(op.action.span()=>(||#action)());
+
+                    let action = if let Some((lpos_name, val_name, rpos_name, wrap_action)) =
+                        &span_capture
+                    {
+                        let wrap_action_span = wrap_action.span().resolved_at(Span::mixed_site());
+                        quote_spanned!(wrap_action_span => (|#lpos_name, #val_name, #rpos_name|#wrap_action)(__lpos, #action, __pos))
+                    } else {
+                        action
+                    };
+
+                    match (&left_arg.expr.expr, &right_arg.expr.expr) {
+                        (&PositionExpr, &PositionExpr) if op.elements.len() == 3 => {
+                            // wrapper rule to capture expression span
+                            match &op.elements[1].expr.expr {
+                                &MarkerExpr(..) => (),
+                                _ => {
+                                    return report_error(op_span, "span capture rule must be `l:position!() n:@ r:position!()".to_string());
+                                }
+                            }
+
+                            span_capture = Some((
+                                name_or_ignore(op.elements[0].name.as_ref()),
+                                name_or_ignore(op.elements[1].name.as_ref()),
+                                name_or_ignore(op.elements[2].name.as_ref()),
+                                &op.action,
+                            ));
+                        }
+                        (&MarkerExpr(la), &MarkerExpr(ra)) if op.elements.len() >= 3 => {
+                            //infix
+                            let new_prec = match (la, ra) {
+                                (true, false) => prec + 1, // left associative
+                                (false, true) => prec,     // right associative
+                                _ => return report_error(op_span, "precedence rules must use `@` and `(@)` to indicate associativity".to_string())
+                            };
+
+                            post_rules.push(
+                                labeled_seq(context, &op.elements[1..op.elements.len()-1], {
+                                    quote_spanned!{ op_span =>
+                                        if let ::peg::RuleResult::Matched(__pos, #r_arg) = __recurse(__pos, #new_prec, __state, __err_state) {
+                                            let #l_arg = __infix_result;
+                                            __infix_result = #action;
+                                            ::peg::RuleResult::Matched(__pos, ())
+                                        } else { ::peg::RuleResult::Failed }
+                                    }
+                                })
+                            );
+                        }
+                        (&MarkerExpr(_), _) if op.elements.len() >= 2 => {
+                            // postfix
+                            post_rules.push(labeled_seq(
+                                context,
+                                &op.elements[1..op.elements.len()],
+                                {
+                                    quote_spanned! { op_span =>
+                                        let #l_arg = __infix_result;
+                                        __infix_result = #action;
+                                        ::peg::RuleResult::Matched(__pos, ())
+                                    }
+                                },
+                            ));
+                        }
+                        (_, &MarkerExpr(a)) if op.elements.len() >= 2 => {
+                            // prefix
+                            let new_prec = match a {
+                                true => prec,
+                                false => prec + 1,
+                            };
+                            pre_rules.push(
+                                labeled_seq(context, &op.elements[..op.elements.len()-1], {
+                                    quote_spanned!{ op_span =>
+                                        if let ::peg::RuleResult::Matched(__pos, #r_arg) = __recurse(__pos, #new_prec, __state, __err_state) {
+                                            ::peg::RuleResult::Matched(__pos, #action)
+                                        } else { ::peg::RuleResult::Failed }
+                                    }
+                                })
+                            );
+                        }
+                        _ => {
+                            // atom
+                            pre_rules.push(labeled_seq(context, &op.elements, {
+                                quote_spanned! { op_span => ::peg::RuleResult::Matched(__pos, #action) }
+                            }));
+                        }
+                    };
+                }
+
+                if !post_rules.is_empty() {
+                    level_code.push(quote_spanned! { span =>
+                        if #prec >= __min_prec {
+                            #(
+                                if let ::peg::RuleResult::Matched(__pos, ()) = #post_rules {
+                                    return (__infix_result, ::peg::RuleResult::Matched(__pos, ()));
+                                }
+                            )*
+                        }
+                    });
+                }
+            }
+
+            let (enter, leave) = if cfg!(feature = "trace") {
+                (
+                    quote_spanned! {span => println!("[PEG_TRACE] Entering level {}", min_prec);},
+                    quote_spanned! {span => println!("[PEG_TRACE] Leaving level {}", min_prec);},
+                )
+            } else {
+                (quote!(), quote!())
+            };
+
+            // The closures below must be defined within the function call to which they are passed
+            // due to https://github.com/rust-lang/rust/issues/41078
+
+            quote_spanned! { span => {
+                fn __infix_parse<T, S>(
+                    state: &mut S,
+                    err_state: &mut ::peg::error::ErrorState,
+                    min_prec: i32,
+                    lpos: usize,
+                    prefix_atom: &Fn(usize, &mut S, &mut ::peg::error::ErrorState, &Fn(usize, i32, &mut S, &mut ::peg::error::ErrorState) -> ::peg::RuleResult<T>) -> ::peg::RuleResult<T>,
+                    level_code: &Fn(usize, usize, i32, T, &mut S, &mut ::peg::error::ErrorState, &Fn(usize, i32, &mut S, &mut ::peg::error::ErrorState) -> ::peg::RuleResult<T>) -> (T, ::peg::RuleResult<()>),
+                ) -> ::peg::RuleResult<T> {
+                    let initial = {
+                        prefix_atom(lpos, state, err_state, &|pos, min_prec, state, err_state| {
+                            __infix_parse(state, err_state, min_prec, pos, prefix_atom, level_code)
+                        })
+                    };
+
+                    if let ::peg::RuleResult::Matched(pos, mut infix_result) = initial {
+                        #enter
+                        let mut repeat_pos = pos;
+                        loop {
+                            let (val, res) = level_code(
+                                repeat_pos,
+                                lpos,
+                                min_prec,
+                                infix_result,
+                                state,
+                                err_state,
+                                &|pos, min_prec, state, err_state| {
+                                    __infix_parse(state, err_state, min_prec, pos, prefix_atom, level_code)
+                                }
+                            );
+                            infix_result = val;
+
+                            if let ::peg::RuleResult::Matched(pos, ()) = res {
+                                repeat_pos = pos;
+                                continue;
+                            }
+
+                            break;
+                        }
+                        #leave
+                        ::peg::RuleResult::Matched(repeat_pos, infix_result)
+                    } else {
+                        ::peg::RuleResult::Failed
+                    }
+                }
+
+                __infix_parse(__state, __err_state, 0, __pos,
+                    &|__pos, __state, __err_state, __recurse| {
+                        let __lpos = __pos;
+                        #(
+                            if let ::peg::RuleResult::Matched(__pos, __v) = #pre_rules {
+                                return ::peg::RuleResult::Matched(__pos, __v);
+                            }
+                        )*
+
+                        ::peg::RuleResult::Failed
+                    },
+                    &|__pos, __lpos, __min_prec, mut __infix_result, __state, __err_state, __recurse| {
+                        #(#level_code)*
+                        (__infix_result, ::peg::RuleResult::Failed)
+                    }
+                )
+            }}
+        }
+        MarkerExpr { .. } => {
+            report_error(span, "`@` is only allowed in `precedence!{}`".to_string())
+        }
+    }
+}