pax_global_header00006660000000000000000000000064147611324720014521gustar00rootroot0000000000000052 comment=79823ff839da42a2b3f11b989ceffa9c117141aa kevinmehall-rust-peg-79823ff/000077500000000000000000000000001476113247200161365ustar00rootroot00000000000000kevinmehall-rust-peg-79823ff/.github/000077500000000000000000000000001476113247200174765ustar00rootroot00000000000000kevinmehall-rust-peg-79823ff/.github/workflows/000077500000000000000000000000001476113247200215335ustar00rootroot00000000000000kevinmehall-rust-peg-79823ff/.github/workflows/rust.yml000066400000000000000000000011371476113247200232550ustar00rootroot00000000000000name: Rust on: push: pull_request: env: CARGO_TERM_COLOR: always jobs: build: name: Rust ${{matrix.rust}} strategy: fail-fast: false matrix: rust: [stable, 1.68.0] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{matrix.rust}} components: rustfmt - name: Check bootstrap run: ./bootstrap.sh && git diff --exit-code - name: Run tests run: cargo test --all - name: Run tests with trace feature run: cargo test --all --features trace kevinmehall-rust-peg-79823ff/.gitignore000066400000000000000000000000761476113247200201310ustar00rootroot00000000000000*~ target peg-macros/grammar_new.rs peg-macros/grammar_old.rs kevinmehall-rust-peg-79823ff/Cargo.lock000066400000000000000000000176061476113247200200550ustar00rootroot00000000000000# This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "glob" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "hashbrown" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "indexmap" version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" dependencies = [ "equivalent", "hashbrown", ] [[package]] name = "itoa" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "once_cell" version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" [[package]] name = "peg" version = "0.8.5" dependencies = [ "peg-macros", "peg-runtime", "trybuild", "version_check", ] [[package]] name = "peg-macros" version = "0.8.5" dependencies = [ "peg-runtime", "proc-macro2", "quote", ] [[package]] name = "peg-runtime" version = "0.8.5" [[package]] name = "proc-macro2" version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] [[package]] name = "ryu" version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" [[package]] name = "serde" version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_json" version = "1.0.139" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" dependencies = [ "itoa", "memchr", "ryu", "serde", ] [[package]] name = "serde_spanned" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] [[package]] name = "syn" version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "termcolor" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "toml" version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" dependencies = [ "serde", "serde_spanned", "toml_datetime", "toml_edit", ] [[package]] name = "toml_datetime" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" version = "0.22.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", "winnow", ] [[package]] name = "trybuild" version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2aa6f84ec205ebf87fb7a0abdbcd1467fa5af0e86878eb6d888b78ecbb10b6d5" dependencies = [ "glob", "once_cell", "serde", "serde_derive", "serde_json", "termcolor", "toml", ] [[package]] name = "unicode-ident" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "winapi-util" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ "windows-sys", ] [[package]] name = "windows-sys" version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1" dependencies = [ "memchr", ] kevinmehall-rust-peg-79823ff/Cargo.toml000066400000000000000000000015551476113247200200740ustar00rootroot00000000000000[workspace] members = ["./peg-macros", "./peg-runtime"] [package] name = "peg" version = "0.8.5" authors = [ "Kevin Mehall " ] license = "MIT" repository = "https://github.com/kevinmehall/rust-peg" description = "A simple Parsing Expression Grammar (PEG) parser generator." keywords = ["peg", "parser", "parsing", "grammar"] categories = ["parsing"] readme = "README.md" edition = "2021" rust-version = "1.68.0" # if changed, also update .github/workflows/rust.yml [dependencies] peg-macros = { path = "./peg-macros", version = "= 0.8.5" } peg-runtime = { path = "./peg-runtime", version = "= 0.8.5" } [dev-dependencies] trybuild = "1.0.80" version_check = "0.9" [[test]] name = "trybuild" path = "tests/trybuild.rs" harness = false [features] default = ["std"] trace = ["peg-macros/trace"] std = ["peg-runtime/std"] unstable = ["peg-runtime/unstable"]kevinmehall-rust-peg-79823ff/LICENSE000066400000000000000000000020401476113247200171370ustar00rootroot00000000000000Copyright (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. kevinmehall-rust-peg-79823ff/README.md000066400000000000000000000074001476113247200174160ustar00rootroot00000000000000# Parsing Expression Grammars in Rust [Documentation](https://docs.rs/peg) | [Release Notes](https://github.com/kevinmehall/rust-peg/releases) `rust-peg` is a simple yet flexible parser generator that makes it easy to write robust parsers. Based on the [Parsing Expression Grammar](https://en.wikipedia.org/wiki/Parsing_expression_grammar) formalism, it provides a Rust macro that builds a recursive descent parser from a concise definition of the grammar. ## Features * Parse input from `&str`, `&[u8]`, `&[T]` or custom types implementing traits * Customizable reporting of parse errors * Rules can accept arguments to create reusable rule templates * Precedence climbing for prefix/postfix/infix expressions * Helpful `rustc` error messages for errors in the grammar definition or the Rust code embedded within it * Rule-level tracing to debug grammars ## Example Parse a comma-separated list of numbers surrounded by brackets into a `Vec`: ```rust peg::parser!{ grammar list_parser() for str { rule number() -> u32 = n:$(['0'..='9']+) {? n.parse().or(Err("u32")) } pub rule list() -> Vec = "[" l:(number() ** ",") "]" { l } } } pub fn main() { assert_eq!(list_parser::list("[1,1,2,3,5,8]"), Ok(vec![1, 1, 2, 3, 5, 8])); } ``` [See the tests for more examples](./tests/run-pass/) [Grammar rule syntax reference in rustdoc](https://docs.rs/peg) ## Comparison with similar parser generators | crate | parser type | action code | integration | input type | precedence climbing | parameterized rules | streaming input | |----------- |------------- |------------- |-------------------- |------------------------ |--------------------- |-------------------- |----------------- | | peg | PEG | in grammar | proc macro (block) | `&str`, `&[T]`, custom | Yes | Yes | No | | [pest] | PEG | external | proc macro (file) | `&str` | Yes | No | No | | [nom] | combinators | in source | library | `&[u8]`, custom | No | Yes | Yes | | [lalrpop] | LR(1) | in grammar | build script | `&str` | No | Yes | No | [pest]: https://github.com/pest-parser/pest [nom]: https://github.com/geal/nom [lalrpop]: https://github.com/lalrpop/lalrpop ## See also * [pegviz] is a UI for visualizing rust-peg's trace output to debug parsers. * There exist several crates to format diagnostic messages on source code snippets in the terminal, including [chic], [annotate-snippets], [codespan-reporting], and [codemap-diagnostic]. [pegviz]: https://github.com/fasterthanlime/pegviz [chic]: https://crates.io/crates/chic [annotate-snippets]: https://crates.io/crates/annotate-snippets [codespan-reporting]: https://crates.io/crates/codespan-reporting [codemap-diagnostic]: https://crates.io/crates/codemap-diagnostic ## Development The `rust-peg` grammar is written in `rust-peg`: `peg-macros/grammar.rustpeg`. To avoid the circular dependency, a precompiled grammar is checked in as `peg-macros/grammar.rs`. To regenerate this, run the `./bootstrap.sh` script. There is a large test suite which uses [`trybuild`](https://crates.io/crates/trybuild) to test both functionality (`tests/run-pass`) and error messages for incorrect grammars (`tests/compile-fail`). Because `rustc` error messages change, the `compile-fail` tests are only run on the minimum supported Rust version to avoid spurious failures. Use `cargo test` to run the entire suite, or `cargo test -- trybuild trybuild=lifetimes.rs` to test just the indicated file. Add `--features trace` to trace these tests. kevinmehall-rust-peg-79823ff/bootstrap.sh000077500000000000000000000006371476113247200205200ustar00rootroot00000000000000#!/bin/sh set -e cargo run -p peg-macros -- peg-macros/grammar.rustpeg > peg-macros/grammar_new.rs mv peg-macros/grammar.rs peg-macros/grammar_old.rs cp peg-macros/grammar_new.rs peg-macros/grammar.rs if cargo run -p peg-macros -- peg-macros/grammar.rustpeg > peg-macros/grammar_new.rs then diff -qs peg-macros/grammar.rs peg-macros/grammar_new.rs rustfmt peg-macros/grammar.rs else echo "Failed" fi kevinmehall-rust-peg-79823ff/peg-macros/000077500000000000000000000000001476113247200201735ustar00rootroot00000000000000kevinmehall-rust-peg-79823ff/peg-macros/Cargo.toml000066400000000000000000000010361476113247200221230ustar00rootroot00000000000000[package] name = "peg-macros" version = "0.8.5" authors = [ "Kevin Mehall " ] license = "MIT" repository = "https://github.com/kevinmehall/rust-peg" description = "Procedural macros for rust-peg. To use rust-peg, see the `peg` crate." edition = "2021" [dependencies] quote = "1.0" proc-macro2 = "1.0.24" peg-runtime = { version = "= 0.8.5", 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 kevinmehall-rust-peg-79823ff/peg-macros/LICENSE000077700000000000000000000000001476113247200224132../LICENSEustar00rootroot00000000000000kevinmehall-rust-peg-79823ff/peg-macros/analysis.rs000066400000000000000000000222671476113247200223750ustar00rootroot00000000000000use proc_macro2::Span; use std::collections::HashMap; use crate::ast::*; pub struct GrammarAnalysis<'a> { pub rules: HashMap, pub left_recursion: Vec, pub loop_nullability: Vec, } 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, rules: &'a HashMap, errors: Vec, } pub struct LeftRecursionError { pub span: Span, pub path: Vec, } 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) -> (HashMap, Vec) { let mut visitor = LeftRecursionVisitor { rules, errors: Vec::new(), stack: Vec::new(), }; let mut rule_nullability: HashMap = 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(_, _) | CustomExpr(_) | 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, errors: Vec, } 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) -> Vec { 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(_, _) | CustomExpr(_) | FailExpr(_) | MarkerExpr(_) => false, PositionExpr => true, } } } kevinmehall-rust-peg-79823ff/peg-macros/ast.rs000066400000000000000000000063201476113247200213310ustar00rootroot00000000000000use proc_macro2::{Group, Ident, Literal, Span, TokenStream}; #[derive(Debug)] pub struct Grammar { pub doc: Option, pub visibility: Option, pub name: Ident, pub lifetime_params: Option>, pub args: Vec<(Ident, TokenStream)>, pub items: Vec, pub input_type: TokenStream, } impl Grammar { pub fn iter_rules(&self) -> impl Iterator { 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>, pub params: Vec, pub expr: SpannedExpr, pub ret_type: Option, pub where_clause: Option, pub doc: Option, pub visibility: Option, pub cache: Option, 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, 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, Option, Vec), MethodExpr(Ident, TokenStream), CustomExpr(Group), ChoiceExpr(Vec), OptionalExpr(Box), Repeat { inner: Box, bound: BoundedRepeat, sep: Option> }, PosAssertExpr(Box), NegAssertExpr(Box), ActionExpr(Vec, Option), MatchStrExpr(Box), PositionExpr, QuietExpr(Box), FailExpr(Group), PrecedenceExpr { levels: Vec, }, 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, } #[derive(Debug, Clone)] pub struct PrecedenceOperator { pub span: Span, pub elements: Vec, pub action: Group, } #[derive(Debug, Clone)] pub enum BoundedRepeat { None, Plus, Exact(TokenStream), Both(Option, Option), } 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 } } } kevinmehall-rust-peg-79823ff/peg-macros/bin.rs000066400000000000000000000031671476113247200213200ustar00rootroot00000000000000//! 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::>(); 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(); } kevinmehall-rust-peg-79823ff/peg-macros/grammar.rs000066400000000000000000010373211476113247200221760ustar00rootroot00000000000000// Generated by rust-peg. Do not edit. pub mod peg { #[allow(unused_imports)] use super::*; type Input = FlatTokenStream; type PositionRepr = ::PositionRepr; #[allow(unused_parens)] struct ParseState<'input> { _phantom: ::core::marker::PhantomData<(&'input ())>, primary_cache: ::std::collections::HashMap>, } impl<'input> ParseState<'input> { fn new() -> ParseState<'input> { ParseState { _phantom: ::core::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, ) -> ::core::result::Result> { #![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::Matched(__pos, __value) => { if ::peg::Parse::is_eof(__input, __pos) { panic!( "Parser is nondeterministic: succeeded when reparsing for error position" ); return Ok(__value); } 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 { #![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> { #![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) => { 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, (|| p)()) } ::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_grammar_args<'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 = { 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 { #![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) => { { let __seq_res = match { let str_start = __pos ; match match __parse_rust_where_clause (__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 , } } { :: 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 , where_clause) => { 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 , where_clause , 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 => { ::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> { #![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 { #![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 { #![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> { #![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 { 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; } } } if __repeat_value.len() >= 1 { ::peg::RuleResult::Matched(__repeat_pos, __repeat_value) } else { ::peg::RuleResult::Failed } }; match __seq_res { ::peg::RuleResult::Matched(__pos, x) => { 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, (|| x)()) } ::peg::RuleResult::Failed => ::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, params) => { match ::peg::ParseLiteral::parse_string_literal(__input, __pos, ")") { ::peg::RuleResult::Matched(__pos, __val) => { ::peg::RuleResult::Matched(__pos, (|| params.unwrap_or_default())()) } ::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 { #![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> { #![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> { #![allow(non_snake_case, unused, clippy::redundant_closure_call)] match { let str_start = __pos; match 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 } } { ::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 { #![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 __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 , _) => { { 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 , ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: 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 , "\"::\"") ; :: 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 = { 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_ty_param_bound( __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, "\"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 = { 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_ty_param_bound( __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, "\"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 = match { 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 ; } } } if __repeat_value.len() >= 1 { ::peg::RuleResult::Matched( __repeat_pos, (), ) } else { ::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) => { :: 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 , ()) } :: peg :: RuleResult :: Failed => :: 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 , _) => { 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 => { let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "<") { :: 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 , _) => { { let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "as") { :: peg :: RuleResult :: Matched (__pos , __val) => { { 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 => { __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 , "\"<\"") ; :: 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 } } } } } } } } } } } } } } 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, _) => { let __seq_res = { let __choice_res = match __parse_rust_generic_args( __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 __parse_PAREN_GROUP (__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 = 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 , "\"->\"") ; :: 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 __seq_res { ::peg::RuleResult::Matched(__pos, _) => { ::peg::RuleResult::Matched(__pos, ()) } ::peg::RuleResult::Failed => { ::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> { #![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) => { 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, (|| p)()) } ::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_rust_where_clause<'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, "where") { ::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 = { 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 match __parse_rust_for_lifetimes( __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 __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, _) => { 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_ty_param_bound (__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::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; } } } ::peg::RuleResult::Matched(__repeat_pos, ()) }; match __seq_res { ::peg::RuleResult::Matched(__pos, _) => { 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, ()) } ::peg::RuleResult::Failed => ::peg::RuleResult::Failed, } } ::peg::RuleResult::Failed => ::peg::RuleResult::Failed, } } ::peg::RuleResult::Failed => { __err_state.mark_failure(__pos, "\"where\""); ::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 = match __parse_rust_ty_param_bound( __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, } } } } } fn __parse_rust_for_lifetimes<'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, "for") { ::peg::RuleResult::Matched(__pos, __val) => { let __seq_res = match __parse_rust_ty_params(__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, "\"for\""); ::peg::RuleResult::Failed } } } fn __parse_rust_ty_param_bound<'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_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 = { 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 match __parse_rust_for_lifetimes( __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 __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, } } ::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 = 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 match __parse_rust_for_lifetimes( __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 __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 , _) => { 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 => ::peg::RuleResult::Failed, } } ::peg::RuleResult::Failed => { __err_state.mark_failure(__pos, "\"(\""); ::peg::RuleResult::Failed } } } } } } } } fn __parse_rust_generic_args<'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 = { 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, _) => { 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, ()) } ::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_expression<'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)] __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 { #![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 { #![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 { #![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 { #![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 { #![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 { #![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 { #![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 { #![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) => { { let __seq_res = __parse_PAREN_GROUP (__input , __state , __err_state , __pos) ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , s) => { :: peg :: RuleResult :: Matched (__pos , (|| { FailExpr (s) . at (sp) }) ()) } :: 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 , "\"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, None, 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, ) => { let __seq_res = match { let str_start = __pos ; match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "::") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = match __parse_rust_generic_args (__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 } } { :: 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) } , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , generics) => { 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 , generics , 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 } } } ::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 => { 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_BRACE_GROUP (__input , __state , __err_state , __pos) ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , code) => { :: peg :: RuleResult :: Matched (__pos , (|| { CustomExpr (code) . 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 => 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 { #![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 = ::peg::call_custom_closure( (|input, pos| input.eat_until(pos, ',')), __input, __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 { #![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 { #![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 { #![allow(non_snake_case, unused, clippy::redundant_closure_call)] ::peg::call_custom_closure((|input, pos| input.next_span(pos)), __input, __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, "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 => { let __choice_res = 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 } }; match __choice_res { ::peg::RuleResult::Matched(__pos, __value) => { ::peg::RuleResult::Matched(__pos, __value) } ::peg::RuleResult::Failed => { match ::peg::ParseLiteral::parse_string_literal( __input, __pos, "where", ) { ::peg::RuleResult::Matched(__pos, __val) => { ::peg::RuleResult::Matched(__pos, __val) } ::peg::RuleResult::Failed => { __err_state.mark_failure(__pos, "\"where\""); ::peg::RuleResult::Failed } } } } } } } } } } } } fn __parse_IDENT<'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 = { __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 = ::peg::call_custom_closure((|input, pos| input.ident(pos)), __input, __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 { #![allow(non_snake_case, unused, clippy::redundant_closure_call)] ::peg::call_custom_closure((|input, pos| input.literal(pos)), __input, __pos) } fn __parse_PAREN_GROUP<'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)] ::peg::call_custom_closure( (|input, pos| input.group(pos, Delimiter::Parenthesis)), __input, __pos, ) } fn __parse_BRACE_GROUP<'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)] ::peg::call_custom_closure( (|input, pos| input.group(pos, Delimiter::Brace)), __input, __pos, ) } fn __parse_BRACKET_GROUP<'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)] ::peg::call_custom_closure( (|input, pos| input.group(pos, Delimiter::Bracket)), __input, __pos, ) } 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, } } } kevinmehall-rust-peg-79823ff/peg-macros/grammar.rustpeg000066400000000000000000000164741476113247200232500ustar00rootroot00000000000000pub 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 = "<" 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})? where_clause:$(rust_where_clause())? "=" expr:expression() ";"? { Rule { span, doc, name:header.0, ty_params:header.1, params:header.2, expr, ret_type, where_clause, visibility, no_eof, cache } } rule cacheflag() -> Option = "#" "[" "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 = "(" params:(x:(name:IDENT() ":" ty:rule_param_ty() { RuleParam { name, ty} }) ++ "," ","? {x})? ")" { params.unwrap_or_default() } rule item() -> Item = u:rust_use() { Item::Use(u) } / r:peg_rule() { Item::Rule(r) } rule rust_doc_comment() -> Option = $(("#" "[" "doc" "=" LITERAL() "]")*)? rule rust_visibility() -> Option = $("pub" PAREN_GROUP()?)? 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_ty_param_bound() ++ "+" / "impl" rust_ty_param_bound() ++ "+" / "(" (rust_type() ++ "," ","?)? ")" / ("<" rust_type() ("as" rust_ty_path())? ">")? rust_ty_path() rule rust_ty_path() = "::"? (IDENT() ("::"? (rust_generic_args() / PAREN_GROUP() ("->" rust_type())?))?) ++ "::" rule rust_ty_params() -> Vec = "<" p:($(rust_generic_param()) ++ ",") ","? ">" { p } rule rust_where_clause() = "where" ( LIFETIME() (":" LIFETIME() ++ "+")? / rust_for_lifetimes()? rust_type() ":" rust_ty_param_bound() ++ "+" ) ** "," ","? rule rust_generic_param() = LIFETIME() (":" LIFETIME() ++ "+")? / IDENT() (":" rust_ty_param_bound() ++ "+")? rule rust_for_lifetimes() = "for" rust_ty_params() rule rust_ty_param_bound() = LIFETIME() / "?"? rust_for_lifetimes()? rust_ty_path() / "(" "?"? rust_for_lifetimes()? rust_ty_path() ")" rule rust_generic_args() = "<" (LIFETIME() / rust_type() / BRACE_GROUP() / LITERAL()) ++ "," ","? ">" 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:PAREN_GROUP() { FailExpr(s).at(sp) } / &("_" / "__" / "___") sp:sp() name:IDENT() { RuleExpr(name, None, Vec::new()).at(sp) } / sp:sp() name:IDENT() generics:$("::" rust_generic_args())? "(" args:(rule_arg() ** ",") ")" { RuleExpr(name, generics, 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) } / sp:sp() "#" code:BRACE_GROUP() { CustomExpr(code).at(sp) } / "(" expression:expression() ")" { expression } rule rule_arg() -> RuleArg = "<" e:expression() ">" { RuleArg::Peg(e) } / tt:$( #{|input, pos| input.eat_until(pos, ',')}+ ) { 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 = #{|input, pos| input.next_span(pos)} rule KEYWORD() = "pub" / "rule" / "use" / "type" / "where" rule IDENT() -> Ident = !KEYWORD() i:#{|input, pos| input.ident(pos)} {i} rule LITERAL() -> Literal = #{|input, pos| input.literal(pos)} rule PAREN_GROUP() -> Group = #{|input, pos| input.group(pos, Delimiter::Parenthesis)} rule BRACE_GROUP() -> Group = #{|input, pos| input.group(pos, Delimiter::Brace)} rule BRACKET_GROUP() -> Group = #{|input, pos| input.group(pos, Delimiter::Bracket)} rule LIFETIME() = "'" IDENT() rule INTEGER() = LITERAL() } kevinmehall-rust-peg-79823ff/peg-macros/lib.rs000066400000000000000000000020701476113247200213060ustar00rootroot00000000000000extern crate proc_macro; extern crate proc_macro2; extern crate quote; use peg::Parse; 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 = if tokens.is_eof(err.location.1) { format!("expected {} at end of input", err.expected) } else { format!("expected {}", err.expected) }; return quote_spanned!(err.location.0=> compile_error!(#msg);).into(); } }; translate::compile_grammar(&grammar).into() } kevinmehall-rust-peg-79823ff/peg-macros/tokens.rs000066400000000000000000000145061476113247200220520ustar00rootroot00000000000000use 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, } #[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, 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 { match self.tokens.get(pos) { Some(t) => RuleResult::Matched(pos, t.span()), _ => RuleResult::Failed, } } pub fn ident(&self, pos: usize) -> RuleResult { match self.tokens.get(pos) { Some(Token::Ident(i)) => RuleResult::Matched(pos + 1, i.clone()), _ => RuleResult::Failed, } } pub fn literal(&self, pos: usize) -> RuleResult { 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 { 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 { let span = self.tokens.get(pos) .map_or_else( || Span::call_site(), |t| t.span() ); Sp(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 } } kevinmehall-rust-peg-79823ff/peg-macros/translate.rs000066400000000000000000001172531476113247200225470ustar00rootroot00000000000000use proc_macro2::Delimiter; 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 { 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 = grammar .args .iter() .map(|&(ref name, ref tp)| quote!(, #name: #tp)) .collect(); quote!(#(#args)*) } fn extra_args_call(grammar: &Grammar) -> TokenStream { let args: Vec = grammar .args .iter() .map(|&(ref name, _)| quote!(, #name)) .collect(); quote!(#(#args)*) } #[derive(Clone)] struct Context<'a> { rules: &'a HashMap, rules_from_args: HashSet, 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(..) = ¶m.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 = 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),*> = 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 = Vec::new(); let mut cache_fields: Vec = 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> }, ); cache_fields.push(name); } } quote_spanned! { span => #[allow(unused_parens)] struct ParseState<'input #(, #grammar_lifetime_params)*> { _phantom: ::core::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: ::core::marker::PhantomData, #(#cache_fields: ::std::collections::HashMap::new()),* } } } } } fn ty_params_slice(ty_params: &Option>) -> &[TokenStream] { ty_params.as_ref().map(|x| &x[..]).unwrap_or(&[]) } fn rule_params_list(context: &Context, rule: &Rule) -> Vec { let Context { input_ty, parse_state_ty, .. } = context; let span = rule.span.resolved_at(Span::mixed_site()); rule.params.iter().map(|param| { let name = ¶m.name; match ¶m.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`. 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 where_clause = rule.where_clause.as_ref().into_iter(); 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: // { 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> #(#where_clause)* { #![allow(non_snake_case, unused, clippy::redundant_closure_call)] #fn_body } } } /// Compile a rule into the parsing function which will be exported. /// Returns `Result`. 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, span = name.span()); let ty_params = ty_params_slice(&rule.ty_params); let where_clause = rule.where_clause.as_ref().into_iter(); let rule_params = rule_params_list(context, rule); let rule_params_call: Vec = rule .params .iter() .map(|param| { let param_name = ¶m.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)* ) -> ::core::result::Result< #ret_ty, ::peg::error::ParseError> > #(#where_clause)* { #![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::Matched(__pos, __value) => { if #eof_check { panic!("Parser is nondeterministic: succeeded when reparsing for error position"); return Ok(__value); // dead code, but needed for type inference } 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) -> 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) }; let pattern = Group::new(Delimiter::None, pattern); 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 generics, 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(), ); } if generics.is_some() { return report_error_expr( rule_name.span(), "rule closure cannot have generics".to_string() ); } quote_spanned! { span=> #rule_name(__input, __state, __err_state, __pos) } } RuleExpr(ref rule_name, ref generics, 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 = 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 #generics (__input, __state, __err_state, __pos #extra_args_call #(, #rule_args_call)*) } } else { quote_spanned! { span=> match #func #generics (__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) } } CustomExpr(ref code) => { let code = code.stream(); quote_spanned! { span=> ::peg::call_custom_closure((#code), __input, __pos) } } 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( state: &mut S, err_state: &mut ::peg::error::ErrorState, min_prec: i32, lpos: usize, prefix_atom: &dyn Fn(usize, &mut S, &mut ::peg::error::ErrorState, &dyn Fn(usize, i32, &mut S, &mut ::peg::error::ErrorState) -> ::peg::RuleResult) -> ::peg::RuleResult, level_code: &dyn Fn(usize, usize, i32, T, &mut S, &mut ::peg::error::ErrorState, &dyn Fn(usize, i32, &mut S, &mut ::peg::error::ErrorState) -> ::peg::RuleResult) -> (T, ::peg::RuleResult<()>), ) -> ::peg::RuleResult { 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()) } } } kevinmehall-rust-peg-79823ff/peg-runtime/000077500000000000000000000000001476113247200203725ustar00rootroot00000000000000kevinmehall-rust-peg-79823ff/peg-runtime/Cargo.toml000066400000000000000000000005211476113247200223200ustar00rootroot00000000000000[package] name = "peg-runtime" version = "0.8.5" authors = [ "Kevin Mehall " ] license = "MIT" repository = "https://github.com/kevinmehall/rust-peg" description = "Runtime support for rust-peg grammars. To use rust-peg, see the `peg` crate." edition = "2021" [lib] path = "lib.rs" [features] std = [] unstable = []kevinmehall-rust-peg-79823ff/peg-runtime/LICENSE000077700000000000000000000000001476113247200226122../LICENSEustar00rootroot00000000000000kevinmehall-rust-peg-79823ff/peg-runtime/error.rs000066400000000000000000000075531476113247200221030ustar00rootroot00000000000000//! Parse error reporting use crate::{Parse, RuleResult}; use std::fmt::{self, Debug, Display}; #[cfg(feature = "std")] use std::collections::BTreeSet; #[cfg(not(feature = "std"))] use {alloc::collections::BTreeSet, alloc::vec::Vec}; /// A set of literals or names that failed to match #[derive(PartialEq, Eq, Debug, Clone)] pub struct ExpectedSet { expected: BTreeSet<&'static str>, } impl ExpectedSet { /// Iterator of expected literals pub fn tokens<'a>(&'a self) -> impl Iterator + 'a { self.expected.iter().map(|x| *x) } } impl Display for ExpectedSet { fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { if self.expected.is_empty() { write!(fmt, "")?; } else if self.expected.len() == 1 { write!(fmt, "{}", self.expected.iter().next().unwrap())?; } else { let mut errors = self.tokens().collect::>(); errors.sort(); let mut iter = errors.into_iter(); write!(fmt, "one of {}", iter.next().unwrap())?; for elem in iter { write!(fmt, ", {}", elem)?; } } Ok(()) } } /// A parse failure. #[derive(PartialEq, Eq, Debug, Clone)] pub struct ParseError { /// The furthest position the parser reached in the input before failing. pub location: L, /// The set of literals that failed to match at that position. pub expected: ExpectedSet, } impl Display for ParseError { fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error> { write!( fmt, "error at {}: expected {}", self.location, self.expected ) } } #[cfg(any(feature = "std", feature = "unstable"))] impl ::std::error::Error for ParseError { fn description(&self) -> &str { "parse error" } } #[doc(hidden)] pub struct ErrorState { /// Furthest failure we've hit so far. pub max_err_pos: usize, /// Are we inside a lookahead/quiet block? If so, failure is disabled. /// Non-zero => yes, to support nested blocks. pub suppress_fail: usize, /// Are we reparsing after a failure? If so, compute and store expected set of all alternative expectations /// when we are at offset `max_err_pos`. pub reparsing_on_error: bool, /// The set of tokens we expected to find when we hit the failure. Updated when `reparsing_on_error`. pub expected: ExpectedSet, } impl ErrorState { pub fn new(initial_pos: usize) -> Self { ErrorState { max_err_pos: initial_pos, suppress_fail: 0, reparsing_on_error: false, expected: ExpectedSet { expected: BTreeSet::new(), }, } } /// Set up for reparsing to record the details of the furthest failure. pub fn reparse_for_error(&mut self) { self.suppress_fail = 0; self.reparsing_on_error = true; } #[inline(never)] pub fn mark_failure_slow_path(&mut self, pos: usize, expected: &'static str) { if pos == self.max_err_pos { self.expected.expected.insert(expected); } } /// Flag a failure. #[inline(always)] pub fn mark_failure(&mut self, pos: usize, expected: &'static str) -> RuleResult<()> { if self.suppress_fail == 0 { if self.reparsing_on_error { self.mark_failure_slow_path(pos, expected); } else if pos > self.max_err_pos { self.max_err_pos = pos; } } RuleResult::Failed } pub fn into_parse_error(self, input: &I) -> ParseError { ParseError { location: Parse::position_repr(input, self.max_err_pos.into()), expected: self.expected, } } } kevinmehall-rust-peg-79823ff/peg-runtime/lib.rs000066400000000000000000000044071476113247200215130ustar00rootroot00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(feature = "unstable", feature(error_in_core))] use std::fmt::Display; pub mod error; mod slice; pub mod str; /// The result type used internally in the parser. /// /// You'll only need this if implementing the `Parse*` traits for a custom input /// type, or using the `#{}` syntax to embed a custom Rust snippet within the parser. /// /// The public API of a parser adapts errors to `std::result::Result` instead of using this type. #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] pub enum RuleResult { /// Success, with final location Matched(usize, T), /// Failure (furthest failure location is not yet known) Failed, } /// A type that can be used as input to a parser. #[allow(clippy::needless_lifetimes)] pub trait Parse { type PositionRepr: Display; fn start<'input>(&'input self) -> usize; fn is_eof<'input>(&'input self, p: usize) -> bool; fn position_repr<'input>(&'input self, p: usize) -> Self::PositionRepr; } /// A parser input type supporting the `[...]` syntax. pub trait ParseElem<'input>: Parse { /// Type of a single atomic element of the input, for example a character or token type Element: Copy; /// Get the element at `pos`, or `Failed` if past end of input. fn parse_elem(&'input self, pos: usize) -> RuleResult; } /// A parser input type supporting the `"literal"` syntax. pub trait ParseLiteral: Parse { /// Attempt to match the `literal` string at `pos`, returning whether it /// matched or failed. fn parse_string_literal(&self, pos: usize, literal: &str) -> RuleResult<()>; } /// A parser input type supporting the `$()` syntax. pub trait ParseSlice<'input>: Parse { /// Type of a slice of the input. type Slice; /// Get a slice of input. fn parse_slice(&'input self, p1: usize, p2: usize) -> Self::Slice; } #[cfg(not(feature = "std"))] extern crate alloc; #[cfg(not(feature = "std"))] extern crate core as std; // needed for type inference on the `#{|input, pos| ..}` closure, since there // are different type inference rules on closures in function args. #[doc(hidden)] pub fn call_custom_closure(f: impl FnOnce(I, usize) -> RuleResult, input: I, pos: usize) -> RuleResult { f(input, pos) }kevinmehall-rust-peg-79823ff/peg-runtime/slice.rs000066400000000000000000000023051476113247200220370ustar00rootroot00000000000000use super::{Parse, ParseElem, ParseLiteral, ParseSlice, RuleResult}; impl Parse for [T] { type PositionRepr = usize; #[inline] fn start(&self) -> usize { 0 } #[inline] fn is_eof(&self, pos: usize) -> bool { pos >= self.len() } #[inline] fn position_repr(&self, pos: usize) -> usize { pos } } impl<'input, T: 'input + Copy> ParseElem<'input> for [T] { type Element = T; #[inline] fn parse_elem(&'input self, pos: usize) -> RuleResult { match self[pos..].first() { Some(c) => RuleResult::Matched(pos + 1, *c), None => RuleResult::Failed, } } } impl ParseLiteral for [u8] { #[inline] fn parse_string_literal(&self, pos: usize, literal: &str) -> RuleResult<()> { let l = literal.len(); if self.len() >= pos + l && &self[pos..pos + l] == literal.as_bytes() { RuleResult::Matched(pos + l, ()) } else { RuleResult::Failed } } } impl<'input, T: 'input> ParseSlice<'input> for [T] { type Slice = &'input [T]; #[inline] fn parse_slice(&'input self, p1: usize, p2: usize) -> &'input [T] { &self[p1..p2] } } kevinmehall-rust-peg-79823ff/peg-runtime/str.rs000066400000000000000000000037351476113247200215600ustar00rootroot00000000000000//! Utilities for `str` input use super::{Parse, ParseElem, ParseLiteral, ParseSlice, RuleResult}; use std::fmt::Display; /// Line and column within a string #[derive(PartialEq, Eq, Debug, Clone, Copy)] pub struct LineCol { /// Line (1-indexed) pub line: usize, /// Column (1-indexed) pub column: usize, /// Byte offset from start of string (0-indexed) pub offset: usize, } impl Display for LineCol { fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error> { write!(fmt, "{}:{}", self.line, self.column) } } impl Parse for str { type PositionRepr = LineCol; #[inline] fn start(&self) -> usize { 0 } #[inline] fn is_eof(&self, pos: usize) -> bool { pos >= self.len() } fn position_repr(&self, pos: usize) -> LineCol { let before = &self[..pos]; let line = before.as_bytes().iter().filter(|&&c| c == b'\n').count() + 1; let column = before.chars().rev().take_while(|&c| c != '\n').count() + 1; LineCol { line, column, offset: pos, } } } impl<'input> ParseElem<'input> for str { type Element = char; #[inline] fn parse_elem(&'input self, pos: usize) -> RuleResult { match self[pos..].chars().next() { Some(c) => RuleResult::Matched(pos + c.len_utf8(), c), None => RuleResult::Failed, } } } impl ParseLiteral for str { #[inline] fn parse_string_literal(&self, pos: usize, literal: &str) -> RuleResult<()> { let l = literal.len(); if self.len() >= pos + l && &self.as_bytes()[pos..pos + l] == literal.as_bytes() { RuleResult::Matched(pos + l, ()) } else { RuleResult::Failed } } } impl<'input> ParseSlice<'input> for str { type Slice = &'input str; #[inline] fn parse_slice(&'input self, p1: usize, p2: usize) -> &'input str { &self[p1..p2] } } kevinmehall-rust-peg-79823ff/src/000077500000000000000000000000001476113247200167255ustar00rootroot00000000000000kevinmehall-rust-peg-79823ff/src/lib.rs000066400000000000000000000360121476113247200200430ustar00rootroot00000000000000//! `rust-peg` is a simple yet flexible parser generator that makes it easy to //! write robust parsers. Based on the [Parsing Expression //! Grammar][wikipedia-peg] formalism, it provides a Rust macro that builds a //! recursive descent parser from a concise definition of the grammar. //! //! [wikipedia-peg]: https://en.wikipedia.org/wiki/Parsing_expression_grammar //! //! ## Features //! //! * Parse input from `&str`, `&[u8]`, `&[T]` or custom types implementing //! traits //! * Customizable reporting of parse errors //! * Rules can accept arguments to create reusable rule templates //! * Precedence climbing for prefix/postfix/infix expressions //! * Helpful `rustc` error messages for errors in the grammar definition or the //! Rust code embedded within it //! * Rule-level tracing to debug grammars //! //! ## Overview //! //! The `peg::parser!{}` macro encloses a `grammar NAME() for INPUT_TYPE { ... //! }` definition containing a set of rules which match components of your //! language. //! //! Rules are defined with `rule NAME(PARAMETERS) -> RETURN_TYPE = PEG_EXPR`. //! The body of the rule, following the `=`, is a PEG expression, definining how //! the input is matched to produce a value. //! //! PEG expressions are evaluated at a particular position of the input. When an //! expression matches, it advances the position and optionally returns a value. //! The expression syntax and behavior is [documented //! below](#expression-reference). //! //! The macro expands to a Rust `mod` containing a function for each rule marked //! `pub` in the grammar. To parse an input sequence, call one of these //! functions. The call returns a `Result` carrying either the //! successfully parsed value returned by the rule, or a `ParseError` containing //! the failure position and the set of tokens expected there. //! //! ## Example //! //! Parse a comma-separated list of numbers surrounded by brackets into a `Vec`: //! //! ```rust //! peg::parser!{ //! grammar list_parser() for str { //! rule number() -> u32 //! = n:$(['0'..='9']+) {? n.parse().or(Err("u32")) } //! //! pub rule list() -> Vec //! = "[" l:(number() ** ",") "]" { l } //! } //! } //! //! pub fn main() { //! assert_eq!(list_parser::list("[1,1,2,3,5,8]"), Ok(vec![1, 1, 2, 3, 5, 8])); //! } //! ``` //! //! ## Expression Reference //! //! ### Atoms //! //! * `"keyword"` - _Literal:_ match a literal string. //! * `['0'..='9']` - _Pattern:_ match a single element that matches a Rust `match`-style //! pattern. [(details)](#pattern-expressions) //! * `[^ '0'..='9']` - _Inverted pattern:_ match a single element that does not match a Rust `match`-style //! pattern. [(details)](#pattern-expressions) //! * `some_rule()` - _Rule:_ match a rule defined elsewhere in the grammar and return its //! result. Arguments in the parentheses are Rust expressions. //! * `_` or `__` or `___` - _Rule (underscore):_ As a special case, rule names //! consisting of underscores can be defined and invoked without parentheses. These are //! conventionally used to match whitespace between tokens. //! * `(e)` - _Parentheses:_ wrap an expression into a group to override //! normal precedence. Returns the same value as the inner expression. (Use //! an _Action_ block to set the return value for a sequence). //! //! ### Combining //! //! * `e1 e2 e3` - _Sequence:_ match expressions in sequence (`e1` followed by `e2` followed by //! `e3`), ignoring the return values. //! * `a:e1 e2 b:e3 c:e4 { rust }` - _Action:_ match `e1`, `e2`, `e3`, `e4` in //! sequence, like above. If they match successfully, run the Rust code in //! the block and return its return value. The variable names before the //! colons in the sequence are bound to the results of the //! corresponding expressions. It is important that the Rust code embedded //! in the grammar is deterministic and free of side effects, as it may be //! called multiple times. //! * `a:e1 b:e2 c:e3 {? rust }` - _Conditional action:_ Like above, but the //! Rust block returns a `Result` instead of a value directly. On //! `Ok(v)`, it matches successfully and returns `v`. On `Err(e)`, the match //! of the entire expression fails and it tries alternatives or reports a //! parse failure with the `&str` `e`. //! * `e1 / e2 / e3` - _Ordered choice:_ try to match `e1`. If the match succeeds, return its //! result, otherwise try `e2`, and so on. //! //! ### Repetition //! * `expression?` - _Optional:_ match zero or one repetitions of `expression`. Returns an //! `Option`. //! * `expression*` - _Repeat:_ match zero or more repetitions of `expression` and return the //! results as a `Vec`. //! * `expression+` - _One-or-more:_ match one or more repetitions of `expression` and return the //! results as a `Vec`. //! * `expression*` - _Range repeat:_ match between `n` and `m` repetitions of `expression` //! return the results as a `Vec`. [(details)](#repeat-ranges) //! * `expression ** delim` - _Delimited repeat:_ match zero or more repetitions of `expression` //! delimited with `delim` and return the results as a `Vec`. //! * `expression ** delim` - _Delimited repeat (range):_ match between `n` and `m` repetitions of `expression` //! delimited with `delim` and return the results as a `Vec`. [(details)](#repeat-ranges) //! * `expression ++ delim` - _Delimited repeat (one or more):_ match one or more repetitions of `expression` //! delimited with `delim` and return the results as a `Vec`. //! //! ### Special //! * `$(e)` - _Slice:_ match the expression `e`, and return the slice of the input //! corresponding to the match. //! * `&e` - _Positive lookahead:_ Match only if `e` matches at this position, //! without consuming any characters. //! * `!e` - _Negative lookahead:_ Match only if `e` does not match at this //! position, without consuming any characters. //! * `position!()` - return a `usize` representing the current offset into //! the input without consuming anything. //! * `quiet!{ e }` - match the expression `e`, but don't report literals within it as "expected" in //! error messages. //! * `expected!("something")` - fail to match, and report the specified string as expected //! at the current location. //! * `precedence!{ ... }` - Parse infix, prefix, or postfix expressions by precedence climbing. //! [(details)](#precedence-climbing) //! * `#{|input, pos| ... }` - _Custom:_ The provided closure is passed the full input and current //! parse position, and returns a [`RuleResult`]. //! //! ## Expression details //! //! ### Pattern expressions //! //! The `[pat]` syntax expands into a [Rust `match` //! pattern](https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html) against the next character //! (or element) of the input. //! //! When the pattern begins with `^`, the matching behavior is inverted: //! the expression succeeds only if the pattern does *not* match. //! `[^' ']` matches any character other than a space. //! //! To match sets of characters, use Rust's `..=` inclusive range pattern //! syntax and `|` to match multiple patterns. For example `['a'..='z' | 'A'..='Z']` matches an //! upper or lower case ASCII alphabet character. //! //! If your input type is a slice of an enum type, a pattern could match an enum variant like //! `[Token::Operator('+')]`. //! //! Variables captured by the pattern are accessible in a subsequent action //! block: `[Token::Integer(i)] { i }`. //! //! The pattern expression also evaluates to the matched element, which can be //! captured into a variable or used as the return value of a rule: `c:['+'|'-']`. //! //! Like Rust `match`, pattern expressions support guard expressions: //! `[c if c.is_ascii_digit()]`. //! //! `[_]` matches any single element. As this always matches except at end-of-file, combining it //! with negative lookahead as `![_]` is the idiom for matching EOF in PEG. //! //! ### Repeat ranges //! //! The repeat operators `*` and `**` can be followed by an optional range specification of the //! form `` (exact), `` (min-inclusive), `<,m>` (max-inclusive) or `` (range-inclusive), where `n` and `m` are either //! integers, or a Rust `usize` expression enclosed in `{}`. //! //! ### Precedence climbing //! //! `precedence!{ rules... }` provides a convenient way to parse infix, prefix, and postfix //! operators using the [precedence //! climbing](http://eli.thegreenplace.net/2012/08/02/parsing-expressions-by-precedence-climbing) //! algorithm. //! //! ```rust,no_run //! # peg::parser!{grammar doc() for str { //! # pub rule number() -> i64 = "..." { 0 } //! pub rule arithmetic() -> i64 = precedence!{ //! x:(@) "+" y:@ { x + y } //! x:(@) "-" y:@ { x - y } //! -- //! x:(@) "*" y:@ { x * y } //! x:(@) "/" y:@ { x / y } //! -- //! x:@ "^" y:(@) { x.pow(y as u32) } //! -- //! n:number() { n } //! "(" e:arithmetic() ")" { e } //! } //! # }} //! # fn main() {} //! ``` //! //! Each `--` introduces a new precedence level that binds more tightly than previous precedence //! levels. The levels consist of one or more operator rules each followed by a Rust action //! expression. //! //! The `(@)` and `@` are the operands, and the parentheses indicate associativity. An operator //! rule beginning and ending with `@` is an infix expression. Prefix and postfix rules have one //! `@` at the beginning or end, and atoms do not include `@`. //! //! ## Input types //! //! The first line of the grammar declares an input type. This is normally //! `str`, but `rust-peg` handles input types through a series of traits. The //! library comes with implementations for `str`, `[u8]`, and `[T]`. Define the //! traits below to use your own types as input to `peg` grammars: //! //! * [`Parse`] is the base trait required for all inputs. The others are only required to use the //! corresponding expressions. //! * [`ParseElem`] implements the `[_]` pattern operator, with a method returning the next item of //! the input to match. //! * [`ParseLiteral`] implements matching against a `"string"` literal. //! * [`ParseSlice`] implements the `$()` operator, returning a slice from a span of indexes. //! //! As a more complex example, the body of the `peg::parser!{}` macro itself is //! parsed with `peg`, using a [definition of these traits][gh-flat-token-tree] //! for a type that wraps Rust's `TokenTree`. //! //! [gh-flat-token-tree]: https://github.com/kevinmehall/rust-peg/blob/master/peg-macros/tokens.rs //! //! ## End-of-file handling //! //! Normally, parsers report an error if the top-level rule matches without consuming all the input. //! To allow matching a prefix of the input, add the `#[no_eof]` attribute before `pub rule`. //! Take care to not miss a malformed `x` at the last position if the rule ends with a `x()*` //! repeat expression. //! //! ## Rule parameters //! //! Rules can be parameterized with types, lifetimes, and values, just like Rust functions. //! //! In addition to Rust values, rules can also accept PEG expression fragments as arguments by using //! `rule` as a parameter type. When calling such a rule, use `<>` around a PEG expression in the //! argument list to capture the expression and pass it to the rule. //! //! For example: //! //! ```rust,no_run //! # peg::parser!{grammar doc() for str { //! rule num_radix(radix: u32) -> u32 //! = n:$(['0'..='9']+) {? u32::from_str_radix(n, radix).or(Err("number")) } //! //! rule list(x: rule) -> Vec = "[" v:(x() ** ",") ","? "]" {v} //! //! pub rule octal_list() -> Vec = list() //! # }} //! # fn main() {} //! ``` //! //! ## Failure reporting //! //! When a match fails, position information is automatically recorded to report a set of //! "expected" tokens that would have allowed the parser to advance further. //! //! Some rules should never appear in error messages, and can be suppressed with `quiet!{e}`: //! ```rust,no_run //! # peg::parser!{grammar doc() for str { //! rule whitespace() = quiet!{[' ' | '\n' | '\t']+} //! # }} //! # fn main() {} //! ``` //! //! If you want the "expected" set to contain a more helpful string instead of character sets, you //! can use `quiet!{}` and `expected!()` together: //! //! ```rust,no_run //! # peg::parser!{grammar doc() for str { //! rule identifier() //! = quiet!{[ 'a'..='z' | 'A'..='Z']['a'..='z' | 'A'..='Z' | '0'..='9' ]*} //! / expected!("identifier") //! # }} //! # fn main() {} //! ``` //! //! ## Imports //! //! ```rust,no_run //! mod ast { //! pub struct Expr; //! } //! //! peg::parser!{grammar doc() for str { //! use self::ast::Expr; //! }} //! # fn main() {} //! ``` //! //! The grammar may begin with a series of `use` declarations, just like in Rust, which are //! included in the generated module. Unlike normal `mod {}` blocks, `use super::*` is inserted by //! default, so you don't have to deal with this most of the time. //! //! ## Rustdoc comments //! //! `rustdoc` comments with `///` before a `grammar` or `pub rule` are propagated to the resulting //! module or function: //! //! ```rust,no_run //! # peg::parser!{grammar doc() for str { //! /// Parse an array expression. //! pub rule array() -> Vec = "[...]" { vec![] } //! # }} //! # fn main() {} //! ``` //! //! As with all procedural macros, non-doc comments are ignored by the lexer and can be used like //! in any other Rust code. //! //! ## Caching and left recursion //! //! A `rule` without parameters can be prefixed with `#[cache]` if it is likely //! to be checked repeatedly in the same position. This memoizes the rule result //! as a function of input position, in the style of a [packrat //! parser][wp-peg-packrat]. //! //! [wp-peg-packrat]: https://en.wikipedia.org/wiki/Parsing_expression_grammar#Implementing_parsers_from_parsing_expression_grammars //! //! However, idiomatic code avoids structures that parse the same input //! repeatedly, so the use of `#[cache]` is often not a performance win. Simple //! rules may also be faster to re-match than the additional cost of the hash //! table lookup and insert. //! //! For example, a complex rule called `expr` might benefit from caching if used //! like `expr() "x" / expr() "y" / expr() "z"`, but this could be rewritten to //! `expr() ("x" / "y" / "z")` which would be even faster. //! //! `#[cache_left_rec]` extends the `#[cache]` mechanism with the ability to resolve //! left-recursive rules, which are otherwise an error. //! //! The `precedence!{}` syntax is another way to handle nested operators and avoid //! repeatedly matching an expression rule. //! //! ## Tracing //! //! If you pass the `peg/trace` feature to Cargo when building your project, a //! trace of the rules attempted and matched will be printed to stdout when //! parsing. For example, //! ```sh //! $ cargo run --features peg/trace //! ... //! [PEG_TRACE] Matched rule type at 8:5 //! [PEG_TRACE] Attempting to match rule ident at 8:12 //! [PEG_TRACE] Attempting to match rule letter at 8:12 //! [PEG_TRACE] Failed to match rule letter at 8:12 //! ... //! ``` extern crate peg_macros; extern crate peg_runtime as runtime; pub use peg_macros::parser; pub use runtime::*; kevinmehall-rust-peg-79823ff/tests/000077500000000000000000000000001476113247200173005ustar00rootroot00000000000000kevinmehall-rust-peg-79823ff/tests/compile-fail/000077500000000000000000000000001476113247200216415ustar00rootroot00000000000000kevinmehall-rust-peg-79823ff/tests/compile-fail/cache_with_args.rs000066400000000000000000000002771476113247200253270ustar00rootroot00000000000000extern crate peg; peg::parser!(grammar foo() for str { #[cache] rule foo(x: u32) = "foo" //~ ERROR #[cache] rule ltarg<'a>() -> &'a str = { "" } //~ ERROR }); fn main() {}kevinmehall-rust-peg-79823ff/tests/compile-fail/cache_with_args.stderr000066400000000000000000000005671476113247200262100ustar00rootroot00000000000000error: rules with generics or parameters cannot use #[cache] or #[cache_left_rec] --> $DIR/cache_with_args.rs:5:10 | 5 | rule foo(x: u32) = "foo" //~ ERROR | ^^^ error: rules with generics or parameters cannot use #[cache] or #[cache_left_rec] --> $DIR/cache_with_args.rs:8:10 | 8 | rule ltarg<'a>() -> &'a str = { "" } //~ ERROR | ^^^^^ kevinmehall-rust-peg-79823ff/tests/compile-fail/duplicate_rule.rs000066400000000000000000000003331476113247200252070ustar00rootroot00000000000000extern crate peg; peg::parser!(grammar foo() for str { //~ ERROR the name `__parse_foo` is defined multiple times [E0428] rule foo() = "foo" rule foo() = "xyz" //~ ERROR duplicate rule `foo` }); fn main() {}kevinmehall-rust-peg-79823ff/tests/compile-fail/duplicate_rule.stderr000066400000000000000000000002141476113247200260640ustar00rootroot00000000000000error: duplicate rule `foo` --> $DIR/duplicate_rule.rs:6:10 | 6 | rule foo() = "xyz" //~ ERROR duplicate rule `foo` | ^^^ kevinmehall-rust-peg-79823ff/tests/compile-fail/incomplete_grammar.rs000066400000000000000000000001151476113247200260510ustar00rootroot00000000000000 peg::parser!(); peg::parser!( grammar parser() for str ); fn main() {}kevinmehall-rust-peg-79823ff/tests/compile-fail/incomplete_grammar.stderr000066400000000000000000000011131476113247200267270ustar00rootroot00000000000000error: expected one of "#", "grammar", "pub" at end of input --> tests/compile-fail/incomplete_grammar.rs:2:1 | 2 | peg::parser!(); | ^^^^^^^^^^^^^^ | = note: this error originates in the macro `peg::parser` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected one of "::", "<", "{" at end of input --> tests/compile-fail/incomplete_grammar.rs:4:1 | 4 | / peg::parser!( 5 | | grammar parser() for str 6 | | ); | |_^ | = note: this error originates in the macro `peg::parser` (in Nightly builds, run with -Z macro-backtrace for more info) kevinmehall-rust-peg-79823ff/tests/compile-fail/left_recursion_without_cache.rs000066400000000000000000000007531476113247200301450ustar00rootroot00000000000000extern crate peg; peg::parser!(grammar foo() for str { rule rec() = rec() //~ ERROR left recursive rules create an infinite loop: rec -> rec rule foo() = "foo" foo() / bar() //~ ERROR left recursive rules create an infinite loop: bar -> foo -> bar rule bar() = "bar" bar() / foo() //~ ERROR left recursive rules create an infinite loop: foo -> bar -> foo rule prec() = precedence! { prec() { () } //~ ERROR } }); fn main() {} kevinmehall-rust-peg-79823ff/tests/compile-fail/left_recursion_without_cache.stderr000066400000000000000000000015641476113247200310250ustar00rootroot00000000000000error: left recursive rules create an infinite loop: rec -> rec --> $DIR/left_recursion_without_cache.rs:4:18 | 4 | rule rec() = rec() //~ ERROR left recursive rules create an infinite loop: rec -> rec | ^^^ error: left recursive rules create an infinite loop: foo -> bar -> foo --> $DIR/left_recursion_without_cache.rs:12:11 | 12 | / foo() //~ ERROR left recursive rules create an infinite loop: foo -> bar -> foo | ^^^ error: left recursive rules create an infinite loop: bar -> foo -> bar --> $DIR/left_recursion_without_cache.rs:8:11 | 8 | / bar() //~ ERROR left recursive rules create an infinite loop: bar -> foo -> bar | ^^^ error: left recursive rules create an infinite loop: prec -> prec --> $DIR/left_recursion_without_cache.rs:15:9 | 15 | prec() { () } //~ ERROR | ^^^^ kevinmehall-rust-peg-79823ff/tests/compile-fail/nullable_loop.rs000066400000000000000000000004021476113247200250320ustar00rootroot00000000000000peg::parser!(grammar e() for str { rule nested() = ("a"*)* //~ ERROR rule nested_ok() = ("a"+)* rule nullable() = "x"? rule call() = "foo" nullable()* //~ ERROR rule more_complex() = ("x" / "a"? "b"?)*<2,> //~ ERROR }); fn main() {} kevinmehall-rust-peg-79823ff/tests/compile-fail/nullable_loop.stderr000066400000000000000000000011531476113247200257150ustar00rootroot00000000000000error: loops infinitely because loop body can match without consuming input --> $DIR/nullable_loop.rs:2:27 | 2 | rule nested() = ("a"*)* //~ ERROR | ^ error: loops infinitely because loop body can match without consuming input --> $DIR/nullable_loop.rs:8:35 | 8 | rule call() = "foo" nullable()* //~ ERROR | ^ error: loops infinitely because loop body can match without consuming input --> $DIR/nullable_loop.rs:10:44 | 10 | rule more_complex() = ("x" / "a"? "b"?)*<2,> //~ ERROR | ^ kevinmehall-rust-peg-79823ff/tests/compile-fail/rule_args_errors.rs000066400000000000000000000004531476113247200255700ustar00rootroot00000000000000extern crate peg; peg::parser!(grammar foo() for str { rule foo(x: i32, y: rule<()>) = "foo" rule ok() = foo(1, <[_] {}>) rule too_few() = foo(1) //~ ERROR rule too_many() = foo(1, <[_] {}>, 2) //~ ERROR pub rule pub_rule_arg(x: rule<()>) = "foo" //~ ERROR }); fn main() {}kevinmehall-rust-peg-79823ff/tests/compile-fail/rule_args_errors.stderr000066400000000000000000000010601476113247200264420ustar00rootroot00000000000000error: this rule takes 2 parameters but 1 parameters were supplied --> $DIR/rule_args_errors.rs:7:22 | 7 | rule too_few() = foo(1) //~ ERROR | ^^^ error: this rule takes 2 parameters but 3 parameters were supplied --> $DIR/rule_args_errors.rs:8:23 | 8 | rule too_many() = foo(1, <[_] {}>, 2) //~ ERROR | ^^^ error: parameters on `pub rule` must be Rust types --> $DIR/rule_args_errors.rs:10:27 | 10 | pub rule pub_rule_arg(x: rule<()>) = "foo" //~ ERROR | ^ kevinmehall-rust-peg-79823ff/tests/compile-fail/rust_action_syntax_error.rs000066400000000000000000000002121476113247200273530ustar00rootroot00000000000000extern crate peg; peg::parser!(grammar foo() for str { rule foo() = { + } //~ ERROR expected expression, found `+` }); fn main() {} kevinmehall-rust-peg-79823ff/tests/compile-fail/rust_action_syntax_error.stderr000066400000000000000000000003061476113247200302360ustar00rootroot00000000000000error: expected expression, found `+` --> $DIR/rust_action_syntax_error.rs:4:20 | 4 | rule foo() = { + } //~ ERROR expected expression, found `+` | ^ expected expression kevinmehall-rust-peg-79823ff/tests/compile-fail/rust_action_type_error.rs000066400000000000000000000002111476113247200270050ustar00rootroot00000000000000extern crate peg; struct X; struct Y; peg::parser!(grammar foo() for str { rule foo() -> X = "a" { Y } //~ ERROR }); fn main() {} kevinmehall-rust-peg-79823ff/tests/compile-fail/rust_action_type_error.stderr000066400000000000000000000015261476113247200276760ustar00rootroot00000000000000error[E0308]: mismatched types --> tests/compile-fail/rust_action_type_error.rs:7:27 | 7 | rule foo() -> X = "a" { Y } //~ ERROR | ^^^^^ | | | expected struct `X`, found struct `Y` | arguments to this enum variant are incorrect | help: the type constructed contains `Y` due to the type of the argument passed --> tests/compile-fail/rust_action_type_error.rs:7:27 | 7 | rule foo() -> X = "a" { Y } //~ ERROR | ^^^^^ this argument influences the type of `{{root}}` note: tuple variant defined here --> peg-runtime/lib.rs | | Matched(usize, T), | ^^^^^^^ = note: this error originates in the macro `peg::parser` (in Nightly builds, run with -Z macro-backtrace for more info) kevinmehall-rust-peg-79823ff/tests/compile-fail/syntax_error.rs000066400000000000000000000002351476113247200247460ustar00rootroot00000000000000extern crate peg; peg::parser!(grammar foo() for str { fn asdf() {} //~ ERROR expected one of "#", "crate", "pub", "rule", "use", "}" }); fn main() {} kevinmehall-rust-peg-79823ff/tests/compile-fail/syntax_error.stderr000066400000000000000000000003101476113247200256170ustar00rootroot00000000000000error: expected one of "#", "pub", "rule", "use", "}" --> tests/compile-fail/syntax_error.rs:4:5 | 4 | fn asdf() {} //~ ERROR expected one of "#", "crate", "pub", "rule", "use", "}" | ^^ kevinmehall-rust-peg-79823ff/tests/compile-fail/use_undefined_result.rs000066400000000000000000000003151476113247200264210ustar00rootroot00000000000000extern crate peg; peg::parser!(grammar foo() for str { rule foo() = "asdf" rule bar() -> u32 = x:foo() { 0 } //~ ERROR using result of rule `foo`, which does not return a value }); fn main() {} kevinmehall-rust-peg-79823ff/tests/compile-fail/use_undefined_result.stderr000066400000000000000000000003741476113247200273050ustar00rootroot00000000000000error: using result of rule `foo`, which does not return a value --> $DIR/use_undefined_result.rs:6:27 | 6 | rule bar() -> u32 = x:foo() { 0 } //~ ERROR using result of rule `foo`, which does not return a value | ^^^ kevinmehall-rust-peg-79823ff/tests/compile-fail/use_undefined_rule.rs000066400000000000000000000002001476113247200260430ustar00rootroot00000000000000extern crate peg; peg::parser!(grammar foo() for str { rule bar() = foo() //~ ERROR undefined rule `foo` }); fn main() {} kevinmehall-rust-peg-79823ff/tests/compile-fail/use_undefined_rule.stderr000066400000000000000000000002301476113247200267250ustar00rootroot00000000000000error: undefined rule `foo` --> $DIR/use_undefined_rule.rs:4:18 | 4 | rule bar() = foo() //~ ERROR undefined rule `foo` | ^^^ kevinmehall-rust-peg-79823ff/tests/run-pass/000077500000000000000000000000001476113247200210505ustar00rootroot00000000000000kevinmehall-rust-peg-79823ff/tests/run-pass/arithmetic.rs000066400000000000000000000015111476113247200235450ustar00rootroot00000000000000extern crate peg; use arithmetic::expression; peg::parser!( grammar arithmetic() for str { pub rule expression() -> i64 = sum() rule sum() -> i64 = l:product() "+" r:product() { l+r } / product() rule product() -> i64 = l:atom() "*" r:atom() { l*r } / atom() rule atom() -> i64 = number() / "(" v:sum() ")" { v } rule number() -> i64 = n:$(['0'..='9']+) { n.parse().unwrap() } }); fn main() { assert_eq!(expression("1+1"), Ok(2)); assert_eq!(expression("5*5"), Ok(25)); assert_eq!(expression("222+3333"), Ok(3555)); assert_eq!(expression("2+3*4"), Ok(14)); assert_eq!(expression("(2+2)*3"), Ok(12)); assert!(expression("(22+)+1").is_err()); assert!(expression("1++1").is_err()); assert!(expression("3)+1").is_err()); } kevinmehall-rust-peg-79823ff/tests/run-pass/arithmetic_ast.rs000066400000000000000000000036201476113247200244170ustar00rootroot00000000000000extern crate peg; use peg::parser; #[derive(Clone, PartialEq, Eq, Debug)] pub enum Expression { Number(i64), Sum(Box, Box), Product(Box, Box), } parser!{ /// Doc comment grammar arithmetic() for str { /// Top level parser rule /// This doc comment has multiple lines to test support for that as well pub rule expression() -> Expression = sum() rule _ = [' ' | '\n']* rule sum() -> Expression = l:product() _ "+" _ r:product() { Expression::Sum(Box::new(l), Box::new(r)) } / product() rule product() -> Expression = l:atom() _ "*" _ r:atom() { Expression::Product(Box::new(l), Box::new(r)) } / atom() rule atom() -> Expression = number() / "(" _ v:sum() _ ")" { v } rule number() -> Expression = n:$(['0'..='9']+) { Expression::Number(n.parse().unwrap()) } }} fn main() { assert_eq!(arithmetic::expression("1+1"), Ok(Expression::Sum( Box::new(Expression::Number(1)), Box::new(Expression::Number(1))) )); assert_eq!(arithmetic::expression("5*5"), Ok(Expression::Product( Box::new(Expression::Number(5)), Box::new(Expression::Number(5))) )); assert_eq!(arithmetic::expression("2+3*4"), Ok(Expression::Sum( Box::new(Expression::Number(2)), Box::new(Expression::Product( Box::new(Expression::Number(3)), Box::new(Expression::Number(4)) )), ))); assert_eq!(arithmetic::expression("(2+3) * 4"), Ok(Expression::Product( Box::new(Expression::Sum( Box::new(Expression::Number(2)), Box::new(Expression::Number(3)), )), Box::new(Expression::Number(4)) ))); assert!(arithmetic::expression("(22+)+1").is_err()); assert!(arithmetic::expression("1++1").is_err()); assert!(arithmetic::expression("3)+1").is_err()); } kevinmehall-rust-peg-79823ff/tests/run-pass/arithmetic_infix.rs000066400000000000000000000016431476113247200247500ustar00rootroot00000000000000 extern crate peg; peg::parser!( grammar arithmetic() for str { rule number() -> i64 = n:$(['0'..='9']+) { n.parse().unwrap() } pub(crate) rule calculate() -> i64 = precedence!{ x:(@) "+" y:@ { x + y } x:(@) "-" y:@ { x - y } "-" v:@ { - v } -- x:(@) "*" y:@ { x * y } x:(@) "/" y:@ { x / y } -- x:@ "^" y:(@) { x.pow(y as u32) } v:@ "!" { (1..v+1).product() } -- "(" v:calculate() ")" { v } n:number() {n} } }); fn main() { assert_eq!(arithmetic::calculate("3+3*3+3"), Ok(15)); assert_eq!(arithmetic::calculate("2+2^2^2^2/2+2"), Ok(32772)); assert_eq!(arithmetic::calculate("1024/2/2/2+1"), Ok(129)); assert_eq!(arithmetic::calculate("1024/(1+1)/2/2+1"), Ok(129)); assert_eq!(arithmetic::calculate("-1-2*-2"), Ok(3)); assert_eq!(arithmetic::calculate("1+3!+1"), Ok(8)); }kevinmehall-rust-peg-79823ff/tests/run-pass/arithmetic_infix_ast.rs000066400000000000000000000020261476113247200256130ustar00rootroot00000000000000extern crate peg; peg::parser!( grammar arithmetic() for str { rule ident() -> &'input str = $(['a'..='z']+) rule haskell_op() -> String = "`" i:ident() "`" [' '|'\n']* { i.to_owned() } rule plus() = "+" [' '|'\n']* pub rule expression() -> InfixAst = precedence!{ x:(@) plus() y:@ { InfixAst::Add(Box::new(x), Box::new(y)) } -- x:(@) op:haskell_op() y:@ { InfixAst::Op(op, Box::new(x), Box::new(y)) } -- i:ident() [' '|'\n']* { InfixAst::Ident(i.to_owned()) } } }); #[derive(Debug, PartialEq, Eq, Clone)] pub enum InfixAst { Ident(String), Add(Box, Box), Op(String, Box, Box) } fn main(){ assert_eq!(arithmetic::expression("a + b `x` c").unwrap(), InfixAst::Add( Box::new(InfixAst::Ident("a".to_owned())), Box::new(InfixAst::Op("x".to_owned(), Box::new(InfixAst::Ident("b".to_owned())), Box::new(InfixAst::Ident("c".to_owned())) )) ) ) }kevinmehall-rust-peg-79823ff/tests/run-pass/arithmetic_infix_ast_span.rs000066400000000000000000000031141476113247200266330ustar00rootroot00000000000000extern crate peg; peg::parser!( grammar arithmetic() for str { rule ident() -> &'input str = $(['a'..='z']+) pub rule expression() -> Node = precedence!{ start:position!() node:@ end:position!() { Node { start, node, end} } -- x:(@) "+" y:@ { Op::Add(Box::new(x), Box::new(y)) } -- x:(@) "*" y:@ { Op::Mul(Box::new(x), Box::new(y)) } -- i:ident() [' '|'\n']* { Op::Ident(i.to_owned()) } } }); #[derive(Debug, PartialEq, Eq, Clone)] pub struct Node { node: Op, start: usize, end: usize, } #[derive(Debug, PartialEq, Eq, Clone)] pub enum Op { Ident(String), Add(Box, Box), Mul(Box, Box), } fn main(){ assert_eq!(arithmetic::expression("a+b*c").unwrap(), Node { start: 0, end: 5, node: Op::Add( Box::new(Node { start: 0, end: 1, node: Op::Ident("a".into()) }), Box::new(Node { start: 2, end: 5, node: Op::Mul( Box::new(Node { start: 2, end: 3, node: Op::Ident("b".into()) }), Box::new(Node { start: 4, end: 5, node: Op::Ident("c".into()) }) ) }) ) } ); }kevinmehall-rust-peg-79823ff/tests/run-pass/arithmetic_with_left_recursion.rs000066400000000000000000000006601476113247200277070ustar00rootroot00000000000000extern crate peg; use arithmetic::sum; peg::parser!( grammar arithmetic() for str { #[cache_left_rec] pub rule sum() -> i64 = l:sum() "+" r:number() { l+r } / number() rule number() -> i64 = n:$(['0'..='9']+) { n.parse().unwrap() } }); fn main() { assert_eq!(sum("1"), Ok(1)); assert_eq!(sum("1+1"), Ok(2)); assert_eq!(sum("1+1+1"), Ok(3)); assert_eq!(sum("1+2+3"), Ok(6)); } kevinmehall-rust-peg-79823ff/tests/run-pass/assembly_ast_dyn_type_param_bounds.rs000066400000000000000000000066161476113247200305620ustar00rootroot00000000000000extern crate peg; use peg::parser; // C++ in Rust trait Operation<'a>: std::fmt::Debug {} trait Operand<'a>: std::fmt::Debug + AsDynOperand<'a> {} trait Location<'a>: Operand<'a> {} impl<'a, T: ?Sized + Location<'a>> Operand<'a> for T {} // Thanks to quinedot for their comprehensive write-up on dyn Traits. // https://quinedot.github.io/rust-learning/dyn-trait-combining.html#manual-supertrait-upcasting trait AsDynOperand<'a> { fn as_dyn_operand(self: Box) -> Box + 'a>; } impl<'a, T: /* Sized + */ Operand<'a> + 'a> AsDynOperand<'a> for T { fn as_dyn_operand(self: Box) -> Box + 'a> { self } } #[derive(Debug)] pub struct Program<'a>(Vec + 'a>>); #[derive(Debug)] struct Add<'a> { result: Box + 'a>, lhs: Box + 'a>, rhs: Box + 'a>, } impl<'a> Operation<'a> for Add<'a> {} #[derive(Debug)] struct Sub<'a> { result: Box + 'a>, lhs: Box + 'a>, rhs: Box + 'a>, } impl<'a> Operation<'a> for Sub<'a> {} #[derive(Debug)] struct Register<'a>(&'a str); impl<'a> Location<'a> for Register<'a> {} #[derive(Debug)] struct Global<'a>(&'a str); impl<'a> Location<'a> for Global<'a> {} #[derive(Debug)] struct Literal(i32); impl<'a> Operand<'a> for Literal {} parser!{ grammar assembly() for str { pub rule program() -> Program<'input> = op:operation() ** "\n" { Program(op) } rule _ = [' ']* rule operation() -> Box + 'input> = a:add() {a} / s:sub() {s} rule add() -> Box> = result:location() _ "=" _ "add" _ lhs:operand() _ rhs:operand() { Box::new(Add{ result, lhs, rhs }) } rule sub() -> Box> = result:location() _ "=" _ "sub" _ lhs:operand() _ rhs:operand() { Box::new(Sub{ result, lhs, rhs }) } rule location() -> Box + 'input> = r:register() {r} / g:global() {g} rule register() -> Box> = "%" _ id:identifier() { Box::new(Register(id)) } rule global() -> Box> = "@" _ id:identifier() { Box::new(Global(id)) } rule identifier() -> &'input str = $(['a'..='z' | 'A'..='Z']+) rule operand() -> Box + 'input> = l:location() {l.as_dyn_operand()} / l:literal() {Box::new(l)} rule literal() -> Literal = n:$(['0'..='9']+) {? let n = n.parse::().map_err(|_| "invalid int literal")?; Ok(Literal(n)) } }} fn main() { let parsed = assembly::program("%apple = add 1 @g @b = add 2 %a %c = sub 82 @b @dog = sub @b 12").unwrap(); let expected = Program(vec![ Box::new(Add{ result: Box::new(Register("apple")), lhs: Box::new(Literal(1)), rhs: Box::new(Global("g")) }), Box::new(Add{ result: Box::new(Global("b")), lhs: Box::new(Literal(2)), rhs: Box::new(Register("a")) }), Box::new(Sub{ result: Box::new(Register("c")), lhs: Box::new(Literal(82)), rhs: Box::new(Global("b")) }), Box::new(Sub{ result: Box::new(Global("dog")), lhs: Box::new(Global("b")), rhs: Box::new(Literal(12)) }), ]); assert_eq!(format!("{parsed:?}"), format!("{expected:?}")); } kevinmehall-rust-peg-79823ff/tests/run-pass/borrow_from_input.rs000066400000000000000000000010061476113247200251670ustar00rootroot00000000000000extern crate peg; peg::parser!(grammar borrows() for str { use std::borrow::{ToOwned, Cow}; pub rule borrowed() -> &'input str = $(['a'..='z']+) pub rule lifetime_parameter() -> Cow<'input, str> = x:$(['a'..='z']+) { x.into() } / "COW" { "cow".to_owned().into() } }); use self::borrows::*; fn main() { assert_eq!(borrowed("abcd"), Ok("abcd")); assert_eq!(&*lifetime_parameter("abcd").unwrap(), "abcd"); assert_eq!(&*lifetime_parameter("COW").unwrap(), "cow"); }kevinmehall-rust-peg-79823ff/tests/run-pass/bytes.rs000066400000000000000000000005231476113247200225440ustar00rootroot00000000000000extern crate peg; use peg::parser; parser!{ grammar byteparser() for [u8] { pub rule commands() -> Vec<&'input[u8]> = command()* rule command() -> &'input [u8] = ">" val:$([b' ' ..= b'~']+) [0] { val } } } fn main() { assert_eq!(byteparser::commands(b">asdf\0>xyz\0"), Ok(vec![&b"asdf"[..], &b"xyz"[..]])); } kevinmehall-rust-peg-79823ff/tests/run-pass/conditional_block.rs000066400000000000000000000033761476113247200251040ustar00rootroot00000000000000extern crate peg; peg::parser!( grammar parse() for str { pub rule dec_byte() -> u8 = match_str:$(['0'..='9']*<,3>) {? let val: u64 = match_str.parse().unwrap(); // only let this rule match if the value is in range 0..255 if val <= 255 { Ok(val as u8) } else { // the message explains what the rule expected and is used in the parse error Err("decimal byte") } } rule tag() -> &'input str = $(['a'..='z']+) pub rule xml() = "<" open:tag() ">" xml()* "" {? if open == close { Ok(()) } else { // TODO this has to be a `&'static str`, so we can't use a dynamic string Err("matching close tag") } } pub rule return_early() -> i32 = vs:$([_]+) {? let v = vs.parse::().map_err(|_| "number")?; if v > 100 { return Err("smaller number"); } Ok(v) } }); fn main() { assert_eq!(parse::dec_byte("0"), Ok(0)); assert_eq!(parse::dec_byte("255"), Ok(255)); assert_eq!(parse::dec_byte("1"), Ok(1)); assert!(parse::dec_byte("256").is_err()); assert!(parse::dec_byte("1234").is_err()); assert!(parse::xml("").is_ok()); assert!(parse::xml("").is_ok()); assert!(parse::xml("").is_err()); assert!(parse::xml("").is_err()); assert!(parse::return_early("a").unwrap_err().expected.tokens().any(|e| e == "number")); assert!(parse::return_early("123").unwrap_err().expected.tokens().any(|e| e == "smaller number")); assert_eq!(parse::return_early("99").unwrap(), 99); } kevinmehall-rust-peg-79823ff/tests/run-pass/crate_import.rs000066400000000000000000000004741476113247200241130ustar00rootroot00000000000000extern crate peg; peg::parser!{ pub grammar foo_parser() for str { use crate::types::Foo; pub rule foo() -> Foo = "foo" { Foo } } } mod types { #[derive(PartialEq, Debug)] pub struct Foo; } fn main() { assert_eq!(foo_parser::foo("foo"), Ok(crate::types::Foo)); } kevinmehall-rust-peg-79823ff/tests/run-pass/custom_expr.rs000066400000000000000000000014641476113247200237730ustar00rootroot00000000000000use peg::RuleResult; peg::parser!( grammar test() for str { rule position() -> usize = #{|input, pos| RuleResult::Matched(pos, pos)} pub rule test1() -> usize = ['a']* p1:position() ['b']* { p1 } pub rule fail() -> usize = #{|input, pos| RuleResult::Failed} rule custom_literal(literal: &str) = #{|input, pos| { let l = literal.len(); if input.len() >= pos + l && &input.as_bytes()[pos..pos + l] == literal.as_bytes() { RuleResult::Matched(pos + l, ()) } else { RuleResult::Failed } }} pub rule test2() = custom_literal("foo") "_" custom_literal("bar") }); fn main() { assert_eq!(test::test1("aaaabb"), Ok(4)); assert_eq!(test::fail("aaaabb").unwrap_err().location.offset, 0); assert_eq!(test::test2("foo_bar"), Ok(())); } kevinmehall-rust-peg-79823ff/tests/run-pass/errors.rs000066400000000000000000000040111476113247200227260ustar00rootroot00000000000000extern crate peg; peg::parser!{ grammar parser() for str { pub rule one_letter() = ['a'..='z'] pub rule parse() -> usize = v:( "a" / "\n" )* { v.len() } pub rule error_pos() = ("a" / "\n" / "\r")* pub rule q() = (quiet!{ ("a" / "b" / "c") ("1" / "2") } / expected!("letter followed by number"))+ pub rule var(s: &'static str) = expected!(s) }} fn main() { // errors at eof assert_eq!(parser::one_letter("t"), Ok(())); let err = parser::one_letter("tt").unwrap_err(); assert_eq!(err.location.line, 1); assert_eq!(err.location.column, 2); assert_eq!(err.location.offset, 1); assert_eq!(format!("{}", err.expected), "EOF"); // expected character set let err = parser::parse(r#" aaaa aaaaaa aaaabaaaa "#).unwrap_err(); assert_eq!(err.location.line, 4); assert_eq!(err.location.column, 5); assert_eq!(err.location.offset, 17); assert_eq!(format!("{}", err.expected), r#"one of "\n", "a", EOF"#); // error position reporting let err = parser::error_pos("aab\n").unwrap_err(); assert_eq!(err.location.line, 1); assert_eq!(err.location.column, 3); assert_eq!(err.location.offset, 2); assert_eq!(err.expected.to_string(), r#"one of "\n", "\r", "a", EOF"#); let err = parser::error_pos("aa\naaaa\nbaaa\n").unwrap_err(); assert_eq!(err.location.line, 3); assert_eq!(err.location.column, 1); let err = parser::error_pos("aa\naaaa\naaab\naa").unwrap_err(); assert_eq!(err.location.line, 3); assert_eq!(err.location.column, 4); let err = parser::error_pos("aa\r\naaaa\r\naaab\r\naa").unwrap_err(); assert_eq!(err.location.line, 3); assert_eq!(err.location.column, 4); parser::q("a1").unwrap(); parser::q("a1b2").unwrap(); let err = parser::q("a1bb").unwrap_err(); assert_eq!(err.location.offset, 2); assert_eq!(err.expected.to_string(), "one of EOF, letter followed by number"); let err = parser::var("", "asdf").unwrap_err(); assert_eq!(err.expected.to_string(), "asdf"); } kevinmehall-rust-peg-79823ff/tests/run-pass/generic_fn_traits.rs000066400000000000000000000011501476113247200251000ustar00rootroot00000000000000extern crate peg; peg::parser!( grammar parser() for str { pub rule foo u32 + Copy>(f: F) -> u32 = s:$(['0'..='9']+) { f(s) } pub rule bar(f: impl Fn(&str) -> u32 + Copy,) -> u32 = s:$(['0'..='9']+) { f(s) } pub rule baz(f: fn(&str) -> u32) -> u32 = s:$(['0'..='9']+) { f(s) } } ); fn main() { let n = parser::foo("123", |s| s.parse().unwrap()).unwrap(); assert_eq!(n, 123); let n = parser::bar("123", |s| s.parse().unwrap()).unwrap(); assert_eq!(n, 123); let n = parser::baz("123", |s| s.parse().unwrap()).unwrap(); assert_eq!(n, 123); } kevinmehall-rust-peg-79823ff/tests/run-pass/grammar_with_args_and_cache.rs000066400000000000000000000002571476113247200270640ustar00rootroot00000000000000extern crate peg; peg::parser! { grammar lol(config: bool) for str { #[cache_left_rec] rule one() -> () = one() / "foo" } } fn main() {} kevinmehall-rust-peg-79823ff/tests/run-pass/keyval.rs000066400000000000000000000010731476113247200227120ustar00rootroot00000000000000extern crate peg; use std::collections::HashMap; peg::parser!( grammar keyval() for str { rule number() -> i64 = n:$(['0'..='9']+) { n.parse().unwrap() } pub rule keyvals() -> HashMap = kvs:keyval() ++ "\n" { kvs.iter().cloned().collect::>() } rule keyval() -> (i64, i64) = k:number() ":" + v:number() { (k, v) } }); fn main() { let mut expected = HashMap::new(); expected.insert(1, 3); expected.insert(2, 4); assert_eq!(keyval::keyvals("1:3\n2:4"), Ok(expected)); } kevinmehall-rust-peg-79823ff/tests/run-pass/lifetimes.rs000066400000000000000000000016021476113247200233760ustar00rootroot00000000000000#[derive(Copy, Clone)] pub struct Token<'text>(&'text str); peg::parser!{ grammar tokenparser<'t>() for [Token<'t>] { pub rule program() -> Vec<&'t str> = list() // add this indirection to ensure that rule args work with a global lifetime rule commasep(x: rule) -> Vec = v:(x() ** [Token(",")]) [Token(",")]? { v } rule list() -> Vec<&'t str> = [Token("(")] l:commasep() [Token(")")] { l } rule string() -> &'t str = [Token(inner)] { inner } #[cache] rule cached() -> Token<'t> = [a] { a } } } peg::parser!{ grammar unused_args<'a>() for () { } } fn main() { let input = "(one,two)"; assert_eq!( tokenparser::program( &[Token(&input[0..1]), Token(&input[1..4]), Token(&input[4..5]), Token(&input[5..8]), Token(&input[8..9])], ), Ok(vec!["one", "two"]) ); } kevinmehall-rust-peg-79823ff/tests/run-pass/memoization.rs000066400000000000000000000004271476113247200237540ustar00rootroot00000000000000extern crate peg; peg::parser!{ grammar memo() for str { #[cache] rule r() -> &'input str = s:$(['a'..='z']+) { s } pub rule parse() = r() "+" r() { () } / r() " " r() { () } }} fn main() { assert_eq!(memo::parse("abc zzz"), Ok(())); } kevinmehall-rust-peg-79823ff/tests/run-pass/no_eof.rs000066400000000000000000000002771476113247200226710ustar00rootroot00000000000000extern crate peg; use peg::parser; parser!{ pub grammar g() for [u8] { #[no_eof] pub rule foo() = "foo" } } fn main() { assert_eq!(g::foo(b"foobar"), Ok(())); } kevinmehall-rust-peg-79823ff/tests/run-pass/optional.rs000066400000000000000000000005451476113247200232470ustar00rootroot00000000000000extern crate peg; peg::parser!( grammar test_grammar() for str { pub rule options() -> Option<()> = "abc" v:"def"? {v} pub rule option_unused_result() = "a"? / "b" }); use self::test_grammar::*; fn main() { assert_eq!(options("abc"), Ok(None)); assert_eq!(options("abcdef"), Ok(Some(()))); assert!(options("def").is_err()); }kevinmehall-rust-peg-79823ff/tests/run-pass/pattern.rs000066400000000000000000000014111476113247200230700ustar00rootroot00000000000000peg::parser!( grammar test() for str { pub rule alphanumeric() = ['a'..='z' | 'A'..='Z' | '0'..='9']* pub rule inverted_pat() -> &'input str = "(" s:$([^')']*) ")" {s} pub rule capture() -> char = ['a'..='z'] pub rule capture2() -> (char, char) = a:['a'..='z'] b:['0'..='9'] { (a, b) } pub rule open_range() -> char = ['a'..] pub rule if_guard() -> char = [x if x.is_ascii_digit()] }); fn main() { assert!(test::alphanumeric("azAZ09").is_ok()); assert!(test::alphanumeric("@").is_err()); assert_eq!(test::inverted_pat("(asdf)"), Ok("asdf")); assert_eq!(test::capture("x"), Ok('x')); assert_eq!(test::capture2("a1"), Ok(('a', '1'))); assert_eq!(test::if_guard("1"), Ok('1')); assert!(test::if_guard("a").is_err()); } kevinmehall-rust-peg-79823ff/tests/run-pass/pos_neg_assert.rs000066400000000000000000000015641476113247200244370ustar00rootroot00000000000000extern crate peg; peg::parser!( grammar lookahead() for str { pub rule consonants() = (!['a'|'e'|'i'|'o'|'u']['a'..='z'])+ pub rule neg_lookahead_err() = !(['a']['b']) ['a']['x'] pub rule lookahead_result() -> &'input str = v:&($(['a'..='c']*)) "abcd" { v } }); fn main() { // negative lookahead assert!(lookahead::consonants("qwrty").is_ok()); assert!(lookahead::consonants("rust").is_err()); // expected characters in negative lookahead should not be reported in parse error messages let err = lookahead::neg_lookahead_err("ac").err().unwrap(); assert_eq!(err.expected.tokens().count(), 1, "expected set includes: {}", err.expected); assert_eq!(err.location.offset, 1); // positive lookahead assert_eq!(lookahead::lookahead_result("abcd"), Ok("abc")); assert!(lookahead::lookahead_result("abc").is_err()); } kevinmehall-rust-peg-79823ff/tests/run-pass/position.rs000066400000000000000000000005001476113247200232550ustar00rootroot00000000000000extern crate peg; peg::parser!(grammar test_grammar() for str { pub rule position() -> (usize, usize, usize) = start:position!() ['a']* middle:position!() ['b']* end:position!() { (start, middle, end) } }); use self::test_grammar::*; fn main() { assert_eq!(position("aaaabbb").unwrap(), (0, 4, 7)); } kevinmehall-rust-peg-79823ff/tests/run-pass/raw_ident.rs000066400000000000000000000002601476113247200233700ustar00rootroot00000000000000extern crate peg; use peg::parser; parser!{ pub grammar g() for str { pub rule r#break() = "foo" } } fn main() { assert_eq!(g::r#break("foo"), Ok(())); } kevinmehall-rust-peg-79823ff/tests/run-pass/renamed_imports.rs000066400000000000000000000004571476113247200246140ustar00rootroot00000000000000extern crate peg; const FOO: i32 = 42; peg::parser!(grammar test_grammar() for str { use super::FOO as F1; use super::{FOO as F2}; pub rule renamed_imports() -> (i32, i32) = { (F1, F2) } }); use self::test_grammar::*; fn main() { assert_eq!(renamed_imports("").unwrap(), (42, 42)); }kevinmehall-rust-peg-79823ff/tests/run-pass/repeats.rs000066400000000000000000000034121476113247200230610ustar00rootroot00000000000000extern crate peg; peg::parser!( grammar repeats() for str { rule number() -> i64 = n:$(['0'..='9']+) { n.parse().unwrap() } pub rule list() -> Vec = number() ** "," rule digit() -> i64 = n:$(['0'..='9']) {n.parse().unwrap() } pub rule repeat_n() -> Vec = digit()*<4> pub rule repeat_min() -> Vec = digit()*<2,> pub rule repeat_max() -> Vec = digit()*<,2> pub rule repeat_min_max() -> Vec = digit()*<2,3> pub rule repeat_sep_3() -> Vec = digit() **<3> "," pub rule repeat_variable() -> Vec<&'input str> = (count:digit() s:$(['a'..='z'|'0'..='9']*<{count as usize}>) {s})* }); use repeats::*; fn main() { assert_eq!(list("5"), Ok(vec![5])); assert_eq!(list("1,2,3,4"), Ok(vec![1,2,3,4])); assert!(repeat_n("123").is_err()); assert_eq!(repeat_n("1234"), Ok(vec![1,2,3,4])); assert!(repeat_n("12345").is_err()); assert!(repeat_min("").is_err()); assert!(repeat_min("1").is_err()); assert_eq!(repeat_min("12"), Ok(vec![1,2])); assert_eq!(repeat_min("123"), Ok(vec![1,2,3])); assert_eq!(repeat_max(""), Ok(vec![])); assert_eq!(repeat_max("1"), Ok(vec![1])); assert_eq!(repeat_max("12"), Ok(vec![1,2])); assert!(repeat_max("123").is_err()); assert!(repeat_min_max("").is_err()); assert!(repeat_min_max("1").is_err()); assert_eq!(repeat_min_max("12"), Ok(vec![1,2])); assert_eq!(repeat_min_max("123"), Ok(vec![1,2,3])); assert!(repeat_min_max("1234").is_err()); assert!(repeat_sep_3("1,2").is_err()); assert!(repeat_sep_3("1,2,3,4").is_err()); assert_eq!(repeat_sep_3("1,2,3"), Ok(vec![1,2,3])); assert_eq!(repeat_variable("1a3abc222"), Ok(vec!["a", "abc", "22"])); }kevinmehall-rust-peg-79823ff/tests/run-pass/return_type.rs000066400000000000000000000006051476113247200237770ustar00rootroot00000000000000use std::fmt::Debug; // `--features trace` code names the return type, so doesn't work with `impl Trait` #[cfg(not(feature = "trace"))] peg::parser!{ grammar g() for str { pub rule returns_impl_trait() -> impl Debug = "" { Box::new(5) } } } fn main() { #[cfg(not(feature = "trace"))] assert_eq!(format!("{:?}", g::returns_impl_trait("")), "Ok(5)"); } kevinmehall-rust-peg-79823ff/tests/run-pass/rule_args.rs000066400000000000000000000040331476113247200234010ustar00rootroot00000000000000extern crate peg; peg::parser!( grammar ra() for str { use peg::ParseLiteral; rule number() -> i64 = n:$(['0'..='9']+) { n.parse().unwrap() } rule commasep(x: rule) -> Vec = v:(x() ** ",") ","? {v} rule bracketed(x: rule) -> T = "[" v:x() "]" {v} pub rule list() -> Vec = commasep() pub rule array() -> Vec = bracketed()>) rule keyword(id: &'static str) = ##parse_string_literal(id) !['0'..='9' | 'a'..='z' | 'A'..='Z' | '_'] rule ident() = ['a'..='z']+ rule _ = [' ']* pub rule ifelse() = keyword("if") _ ident() _ keyword("then") _ ident() _ keyword("else") _ ident() pub rule repeated_a(i: usize) = ['a']*<{i}> rule i(literal: &'static str) = input:$([_]*<{literal.len()}>) {? if input.eq_ignore_ascii_case(literal) { Ok(()) } else { Err(literal) } } pub rule test_i() = i("foo") i("bar") rule recursive(r: rule<()>) = " " recursive(r) // Issue #226 rule complex_args(val1: u32, val2: Option) = { assert_eq!(val1, 10); assert_eq!(val2, Some(8)) } pub rule use_complex_args() = complex_args(u32::max(5, 10), [1,1,3,5,8,13].iter().cloned().find(|x| { x % 2 == 0 })) pub rule lt_arg<'a>() = "" pub rule lt_arg_mut<'a>(x: &'a mut ()) = "" pub rule ty_arg(x: &T) = "" pub rule ty_arg_bound(x: T) = "" pub rule ty_arg_bound2<'a, T: std::marker::Copy + ?Sized + 'a>(x: T) = "" pub rule ty_arg_bound_ret() -> T = {? "".parse().or(Err("oops")) } }); use ra::*; fn main() { assert_eq!(list("1,2,3,4"), Ok(vec![1,2,3,4])); assert_eq!(array("[1,1,2,3,5,]"), Ok(vec![1,1,2,3,5])); assert!(ifelse("if foo then x else y").is_ok()); assert!(ifelse("iffoothenxelsey").is_err()); assert!(repeated_a("aa", 2).is_ok()); assert!(repeated_a("aaa", 2).is_err()); assert!(repeated_a("aaaaa", 5).is_ok()); assert!(test_i("fOoBaR").is_ok()); assert!(test_i("fOoBaZ").is_err()); assert!(test_i("fOoX").is_err()); use_complex_args("").ok(); }kevinmehall-rust-peg-79823ff/tests/run-pass/rule_generic.rs000066400000000000000000000004731476113247200240650ustar00rootroot00000000000000peg::parser!( grammar test() for str { rule number() -> T = s:$(['0'..='9']+) {? s.parse().or(Err("number")) } pub rule numbers() -> (u8, i32) = n1:number::() "," n2:number::() { (n1, n2) } }); fn main() { assert_eq!(test::numbers("42,1234"), Ok((42, 1234))); } kevinmehall-rust-peg-79823ff/tests/run-pass/rule_where_clause.rs000066400000000000000000000011151476113247200251110ustar00rootroot00000000000000extern crate peg; use std::{ str::FromStr, fmt::Debug, }; peg::parser!( grammar parser() for str { use std::cell::Cell; pub rule nums() -> C where C: Default + Extend, T: FromStr, ::Err: Debug, = c:({ Cell::new(C::default()) }) (ch:$(['0'..='9']) { let mut mutc = c.take(); mutc.extend(Some(ch.parse::().unwrap())); c.set(mutc); })+ { c.take() } } ); fn main() { assert_eq!(parser::nums::, u8>("3729"), Ok(vec![3, 7, 2, 9])); } kevinmehall-rust-peg-79823ff/tests/run-pass/test-hygiene.rs000066400000000000000000000007441476113247200240300ustar00rootroot00000000000000use ::peg as realpeg; struct Result; struct ParseResult; struct Parse; struct Input; struct ParseState; struct ErrorState; struct Vec; struct HashMap; mod peg {} realpeg::parser!{ grammar p() for str { pub rule number() -> f64 = n:$(['0'..='9']+) { n.parse().unwrap() } #[cache] pub rule cached() = "x" pub rule prec() -> () = precedence!{ "x" { () } } } } fn main() { assert_eq!(p::number("12345"), Ok(12345.0)) } kevinmehall-rust-peg-79823ff/tests/run-pass/tokens.rs000066400000000000000000000006551476113247200227270ustar00rootroot00000000000000#[derive(Copy, Clone)] pub enum Token { Open, Number(i32), Comma, Close, } peg::parser!{ grammar tokenparser() for [Token] { pub rule list() -> (i32, i32) = [Token::Open] [Token::Number(a)] [Token::Comma] [Token::Number(b)] [Token::Close] { (a, b) } } } fn main() { assert_eq!(tokenparser::list(&[Token::Open, Token::Number(5), Token::Comma, Token::Number(7), Token::Close]), Ok((5, 7))); } kevinmehall-rust-peg-79823ff/tests/run-pass/tokens_struct.rs000066400000000000000000000041531476113247200243300ustar00rootroot00000000000000use peg::{Parse, ParseElem, RuleResult}; /// The default implementation of the parsing traits for `[T]` expects `T` to be /// `Copy`, as in the `[u8]` or simple enum cases. This wrapper exposes the /// elements by `&T` reference, which is `Copy`. pub struct SliceByRef<'a, T>(pub &'a [T]); impl<'a , T> Parse for SliceByRef<'a, T> { type PositionRepr = usize; fn start(&self) -> usize { 0 } fn is_eof(&self, pos: usize) -> bool { pos >= self.0.len() } fn position_repr(&self, pos: usize) -> usize { pos } } impl<'a, T: 'a> ParseElem<'a> for SliceByRef<'a, T> { type Element = &'a T; fn parse_elem(&'a self, pos: usize) -> RuleResult<&'a T> { match self.0[pos..].first() { Some(c) => RuleResult::Matched(pos + 1, c), None => RuleResult::Failed, } } } #[derive(PartialEq)] pub enum TokenType { Word, Number, } pub struct Token { pub token_type: TokenType, pub term: String, } peg::parser!{ grammar tokenparser<'a>() for SliceByRef<'a, Token> { // The [] syntax works just like (and expands into) an arm of a match // in regular Rust, so you can use a pattern that matches one field // and ignores the rest pub rule word_by_field() = [ Token { token_type: TokenType::Word, .. } ] // Or capture the token as a variable and then test it with an if guard. pub rule word_by_eq() = [t if t.token_type == TokenType::Word] // You could wrap this in a rule that accepts the TokenType as an argument rule tok(ty: TokenType) -> &'input Token = [t if t.token_type == ty] pub rule number() = tok(TokenType::Number) } } fn main() { let word_tok = vec![ Token { token_type: TokenType::Word, term: "foo".into() } ]; let number_tok = vec![ Token { token_type: TokenType::Number, term: "123".into() } ]; assert!(tokenparser::word_by_field(&SliceByRef(&word_tok[..])).is_ok()); assert!(tokenparser::word_by_eq(&SliceByRef(&word_tok[..])).is_ok()); assert!(tokenparser::number(&SliceByRef(&number_tok[..])).is_ok()); } kevinmehall-rust-peg-79823ff/tests/run-pass/utf8.rs000066400000000000000000000006371476113247200223120ustar00rootroot00000000000000extern crate peg; peg::parser!(grammar test_grammar() for str { pub rule boundaries() -> String = n:$("foo") { n.to_string() } }); use self::test_grammar::*; // before we were testing string matches using .slice(), which // threw an ugly panic!() when we compared unequal character // boundaries.. this popped up while parsing unicode fn main() { assert!(boundaries("f↙↙↙↙").is_err()); } kevinmehall-rust-peg-79823ff/tests/trybuild.rs000066400000000000000000000016271476113247200215120ustar00rootroot00000000000000fn main() { let args: Vec<_> = std::env::args().collect(); let t = trybuild::TestCases::new(); t.pass("tests/run-pass/*.rs"); let expected_rust_ver = env!("CARGO_PKG_RUST_VERSION"); let run_anyway = args.iter().any(|a| a == "--compile-fail"); let run_compile_fail = run_anyway || version_check::is_exact_version(expected_rust_ver).unwrap_or(true); if run_compile_fail { t.compile_fail("tests/compile-fail/*.rs"); } // Trybuild runs the configured tests on drop drop(t); if !run_compile_fail { eprintln!("!!! Skipped compile-fail tests !!!"); eprintln!("These tests are only checked on rust version {expected_rust_ver} because"); eprintln!("the error message text may change between compiler versions."); eprintln!(""); eprintln!("Run `cargo +{expected_rust_ver} test` to run these tests."); eprintln!(""); } }