pkl_parser/
parser.rs

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