1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
use pest::{
iterators::Pairs,
pratt_parser::{Assoc, Op, PrattParser},
Parser,
};
use pest_derive::Parser;
/// `PklParser` is a parser generated from the `pkl.pest` grammar file.
/// This struct is used to parse input strings according to the rules defined in the grammar.
#[derive(Parser)]
#[grammar = "pkl.pest"]
pub struct PklParser;
/// Parses the given source string using the `PklParser` and returns a `Pairs` iterator over the parsed tokens.
///
/// # Arguments
///
/// * `src` - A string slice that holds the source code to be parsed.
///
/// # Returns
///
/// * `Ok(Pairs<Rule>)` - A successful result containing a `Pairs` iterator over the parsed tokens.
/// * `Err(pest::error::Error<Rule>)` - An error that occurred during parsing, encapsulated in a `pest` error.
///
/// # Example
///
/// ```rust
/// let source = "your source code here";
/// let parsed = parse(source);
/// match parsed {
/// Ok(pairs) => {
/// for pair in pairs {
/// // handle parsed tokens
/// }
/// }
/// Err(error) => {
/// eprintln!("Parsing error: {:?}", error);
/// }
/// }
/// ```
pub fn parse(src: &str) -> Result<Pairs<Rule>, pest::error::Error<Rule>> {
let result = PklParser::parse(Rule::file, src)?;
Ok(result)
}
/// Constructs a `PrattParser` for parsing and evaluating expressions with operator precedence and associativity.
///
/// The `PrattParser` is configured with various infix, prefix, and postfix operators, as specified by the PKL grammar.
/// This is used to handle expressions like arithmetic operations, comparisons, and logical operators.
///
/// # Returns
///
/// * `PrattParser<Rule>` - A configured `PrattParser` for parsing expressions with the appropriate precedence and associativity.
///
/// # Example
///
/// ```rust
/// let pratt_parser = pratt();
/// // Use the pratt_parser to evaluate expressions
/// ```
/// // For how to use the pratt_parser, [see](https://pest.rs/book/precedence.html)
pub fn pratt() -> PrattParser<Rule> {
PrattParser::new()
.op(Op::infix(Rule::null_coalescing, Assoc::Left))
.op(Op::infix(Rule::comp_equal, Assoc::Left)
| Op::infix(Rule::and, Assoc::Left)
| Op::infix(Rule::or, Assoc::Left)
| Op::infix(Rule::comp_not_equal, Assoc::Left)
| Op::infix(Rule::comp_greater, Assoc::Left)
| Op::infix(Rule::comp_greater_equal, Assoc::Left)
| Op::infix(Rule::comp_less, Assoc::Left)
| Op::infix(Rule::comp_less_equal, Assoc::Left))
.op(Op::infix(Rule::is_op, Assoc::Left) | Op::infix(Rule::as_op, Assoc::Left))
.op(Op::infix(Rule::add, Assoc::Left) | Op::infix(Rule::sub, Assoc::Left))
.op(Op::infix(Rule::mul, Assoc::Left)
| Op::infix(Rule::modulo, Assoc::Left)
| Op::infix(Rule::div, Assoc::Left)
| Op::infix(Rule::div_r, Assoc::Left))
.op(Op::infix(Rule::pow, Assoc::Right))
.op(Op::postfix(Rule::non_null))
.op(Op::prefix(Rule::neg) | Op::prefix(Rule::logical_not))
}