Skip to content

Rust

The Rust target generates a standalone module and represents actions, labels, and final results with a Value enum.

Minimal working example

Create a binary crate in an empty directory:

powershell
cargo init --bin --name identifier --edition 2021 .

Create identifier.peg and replace src/main.rs with the content below. src/parser.rs is generated by pegtool.

identifier.peg

peg
Start = value:<Identifier> !. { return value; }
Identifier = [\pL_] [\pL\p{Nd}_]*

src/main.rs

rust
mod parser;

use parser::{PTParser, Value};

fn main() {
    let value = PTParser::parse("name_世界").expect("valid identifier");
    match value {
        Value::String(text) => println!("{text}"),
        other => panic!("unexpected parser result: {other:?}"),
    }
}

Generate and run it:

powershell
pegtool -t rust -o src\parser.rs identifier.peg
cargo run --quiet

Output:

text
name_世界

Value

The generated module provides a cloneable Value enum with these variants:

  • Null
  • String
  • Int
  • Float
  • Bool
  • Array
  • Object
  • Custom

Common accessors include as_str, as_array, and as_i64. Value::custom can store a project type that implements Any.

Actions

peg
Integer = '-'? [0-9]+ {
    match c.text.parse::<i64>() {
        Ok(value) => return Value::Int(value),
        Err(error) => {
            p.add_err(error);
            return Value::Null;
        }
    }
}

The initializer is emitted at module scope and can define helper functions and types. A label is also a Value and must be destructured by variant.

Options

rust
let options = ParserOptions {
    filename: "input.txt".to_owned(),
    entrypoint: Some("Start".to_owned()),
    max_expressions: 1_000_000,
    custom_data: None,
};

let value = PTParser::parse_with_options(source, options)?;

Failures return ParseError. The Rust target currently has no memoization switch, and -optimize-parser has no Rust-specific effect. Choose rule indexing according to real benchmarks and generated-diff requirements.

Released under the BSD 3-Clause License