Skip to main content

Parser

Struct Parser 

Source
pub struct Parser<C: ParserContext> { /* private fields */ }
Expand description

A recursive descent parser for expressions, generic over the ParserContext it emits into.

CELParser is a type alias for Parser<DynSegmentContext> and remains the concrete type most callers use; it behaves identically to how CELParser always has, before this type became generic.

§Examples

§Basic Usage

use cel_parser::OpLookup;
use cel_parser::CELParser;
use proc_macro2::TokenStream;
use std::str::FromStr;

let input = TokenStream::from_str("10").unwrap();
let mut parser = CELParser::new(OpLookup::new());
let result = parser.parse_tokens(input.into_iter());
assert!(result.is_ok());

§Error Formatting

use annotate_snippets::Renderer;
use cel_parser::OpLookup;
use cel_parser::CELParser;
use proc_macro2::TokenStream;
use std::str::FromStr;

let line = line!() + 1;
let source = r#"
  10 + 20 30
"#; // Invalid: missing operator
let input = TokenStream::from_str(source).unwrap();
let mut parser = CELParser::new(OpLookup::new());

if let Err(e) = parser.parse_tokens(input.into_iter()) {
    // Format error starting at line 1
    println!("{}", e.format_rustc_style(source, file!(), line, &Renderer::plain()));
}

Implementations§

Source§

impl<C: ParserContext> Parser<C>

Source

pub fn new(op_lookup: OpLookup) -> Self

Creates a new CEL parser with the given operation lookup.

No tokens are set at construction; use set_tokens, parse_tokens_ctx, or parse_str_ctx to parse.

§Arguments
  • op_lookup - Operation lookup for resolving operators and identifiers
Source

pub fn with_type_resolver<R>(op_lookup: OpLookup, type_resolver: R) -> Self
where R: TypeResolver + 'static,

Creates a new CEL parser with the given operation lookup and leaf type resolver.

Existing callers that need only the built-in CEL scalar types should continue to use new; this constructor is for hosts that want additional named CEL types without coupling cel-parser to their own registry implementation.

§Examples
use cel_parser::{CELParser, OpLookup, ResolvedLeafType};
use cel_runtime::ValueType;

#[derive(Clone)]
struct Celsius(i32);

let resolver = [(
    "Celsius",
    ResolvedLeafType::new("Celsius", ValueType::leaf::<Celsius>()),
)];
let mut segment = CELParser::with_type_resolver(OpLookup::new(), resolver)
    .parse_str("[]: [Celsius]")
    .unwrap();
let array = segment.call0::<cel_runtime::OwnedValue>().unwrap().try_into_typed::<cel_runtime::ArrayOf<cel_runtime::Leaf<Celsius>>>().unwrap();
assert!(array.into_vec().is_empty());
Source

pub fn set_type_resolver<R>(&mut self, type_resolver: R)
where R: TypeResolver + 'static,

Replaces this parser’s named-type resolver.

Every subsequent parse resolves annotation type names through type_resolver instead of the one this parser was built with.

§Examples
use cel_parser::{CELParser, OpLookup, ResolvedLeafType};
use cel_runtime::ValueType;

#[derive(Clone)]
struct Celsius(i32);

let mut parser = CELParser::new(OpLookup::new());
assert!(parser.parse_str("[]: [Celsius]").is_err());

parser.set_type_resolver([(
    "Celsius",
    ResolvedLeafType::new("Celsius", ValueType::leaf::<Celsius>()),
)]);
assert!(parser.parse_str("[]: [Celsius]").is_ok());
Source

pub fn resolve_type_expr(&self, expr: &TypeExpr) -> Result<ResolvedType>

Resolves expr through this parser’s configured leaf type resolver.

§Errors

Returns Err if some named leaf in expr is not recognized.

Source

pub fn set_tokens(&mut self, tokens: TokenStreamIter)

Sets the token stream for parsing, resetting internal state.

Call before is_expression or use parse_tokens_ctx which sets tokens and parses in one step.

Source

pub fn set_lex_tokens(&mut self, tokens: Peekable<LexLexer>)

Sets the token stream from an existing LexLexer iterator for inline expression parsing.

Resets the context. Use together with parse_expression_ctx and take_lex_tokens to share a token stream between adam-lang and CELParser.

Source

pub fn unbalanced_delimiter_count(&self) -> i32

Returns the net number of opening delimiters this parser has consumed since the last set_tokens/set_lex_tokens call, that remain unmatched by a corresponding closing delimiter.

Always 0 after a successful top-level parse: every delimiter this grammar opens (an if-expression’s branch braces, a tuple/group literal’s or call’s parens), it also closes. Positive after a parse that returned Err from partway through a production that had already consumed one or more opening delimiters before failing — e.g. an if-expression whose then-branch fails to parse consumes the branch’s opening { before erroring out, never reaching the matching }.

An embedding caller that shares its own token stream with this parser (via set_lex_tokens/take_lex_tokens), and tracks its own nesting depth over that same stream, cannot otherwise tell a delimiter this parser left dangling apart from one still genuinely open in the caller’s own grammar, since both use the same Delimiter kinds. Reading this count immediately after reclaiming the stream — regardless of whether the parse succeeded or failed — and folding it into the caller’s own depth counter keeps that counter consistent with the physical nesting left behind in the stream.

Source

pub fn parse_expression_ctx(&mut self) -> Result<C>

Parses one expression from the current token stream and returns the built context.

Unlike parse_str_ctx, this method does not require end-of-stream, allowing adam-lang to parse an expression embedded within a larger token stream.

§Errors

Returns an error if the input does not contain a valid expression.

  • Complexity: O(n) in the number of tokens in the expression.
Source

pub fn parse_expression_ctx_restricted( &mut self, restriction: ExpressionRestriction, ) -> Result<C>

Parses one expression under restriction, restoring the previous mode on every result.

Does not require end-of-stream, so the enclosing grammar retains its body brace.

  • Complexity: O(n) in the expression’s token count.
§Errors

Returns an error for a malformed expression or a context’s semantic rejection.

§Examples

See ExpressionRestriction.

Source

pub fn parse_literal_pattern_ctx(&mut self) -> Result<C>

Parses one literal_pattern from the current token stream and returns the built context.

Like parse_expression_ctx, this does not require end-of-stream, letting a caller (e.g. adam-lang’s conditional_branch) parse just the pattern before continuing with its own grammar.

§Errors

Returns an error if the input does not contain a valid literal_pattern.

Source

pub fn take_lex_tokens(&mut self) -> Option<Peekable<LexLexer>>

Returns the remaining token stream after expression parsing.

Call after parse_expression_ctx to recover the shared LexLexer for continued adam-lang parsing.

Source

pub fn parse_tokens_ctx(&mut self, tokens: TokenStreamIter) -> Result<C>

Parses a token stream into a context value.

Sets the token source, runs the expression grammar, and returns the context on success.

§Errors

Returns an error if the input does not contain a valid CEL expression.

Source

pub fn parse_str_ctx(&mut self, s: &str) -> Result<C>

Parses a string into a context value.

Tokenizes the string then parses; equivalent to parse_tokens_ctx(TokenStream::from_str(s)?.into_iter()).

§Errors

Returns an error on lex failure or if the input does not contain a valid CEL expression.

Source

pub fn parse_type_expr(&mut self) -> Result<TypeExpr>

Parses one complete type_expr from the current token stream.

Unlike parse_type_expr_str, this method does not require ownership of the whole source string; it consumes only as many tokens as the type expression itself needs from the current stream.

§Errors

Returns an error if the current token stream does not begin with a valid type expression.

Source

pub fn parse_type_expr_tokens( &mut self, tokens: TokenStreamIter, ) -> Result<TypeExpr>

Parses one complete type_expr from tokens.

§Errors

Returns an error if tokens does not contain a valid complete type expression.

Source

pub fn parse_type_expr_str(&mut self, s: &str) -> Result<TypeExpr>

Parses one complete type_expr from s.

§Errors

Returns an error on lex failure or if s does not contain a valid complete type expression.

Source

pub fn op_lookup_mut(&mut self) -> &mut OpLookup

Returns a mutable reference to the operation lookup.

This allows customization of the operations available during parsing, such as adding new scopes for custom operations or identifiers.

§Examples
use cel_parser::op_table::OpLookup;
use cel_parser::CELParser;
use cel_runtime::DynSegment;
use proc_macro2::TokenStream;
use std::any::TypeId;
use std::str::FromStr;

let input = TokenStream::from_str("10 + 20").unwrap();
let mut lookup = OpLookup::new();
lookup.push_scope(|name, segment, num_operands, _span| {
    let matches = {
        let top = segment.peek_stack_infos(num_operands);
        name == "+" && top.len() == 2 && top[0].value_type.type_id() == TypeId::of::<i32>()
    };
    if matches {
        segment.op2(|a: i32, b: i32| a + b + 1)?; // Custom addition
        Ok(true)
    } else {
        Ok(false)
    }
});
let mut parser = CELParser::new(lookup);
parser.set_tokens(input.into_iter());
Source

pub fn is_expression(&mut self) -> Result<bool>

expression = range_expression.

Source

pub fn parse_type_expression(&mut self) -> Result<TypeExpr>

type_expression = identifier [ "(" [ type_expression { "," type_expression } ] ")" ] | "[" type_expression "]" | "(" [ type_expression ["," [ type_expression { "," type_expression } ]] ] ")" .

() is the empty tuple type (0 elements); (T) is grouping (same as bare T); (T,) is a 1-element tuple; (T, U, ...) is n-element, no trailing comma. [T] names an array type whose elements have type T. Name(A, B) applies zero or more type arguments to a named (generic) type.

§Errors

Returns an error if a named leaf is missing, if an array, tuple, or type-argument list is malformed, or if a closing ]/) is missing.

Source§

impl Parser<DynSegmentContext>

Source

pub fn parse_expression(&mut self) -> Result<DynSegment>

Parses one expression from the current token stream and returns the segment.

Unlike parse_str, this method does not require end-of-stream, allowing adam-lang to parse an expression embedded within a larger token stream.

§Errors

Returns an error if the input does not contain a valid expression.

  • Complexity: O(n) in the number of tokens in the expression.
Source

pub fn parse_expression_restricted( &mut self, restriction: ExpressionRestriction, ) -> Result<DynSegment>

Parses one embedded expression with a header brace restriction.

  • Complexity: O(n) in the expression’s token count.
§Errors

Returns syntax, type, or operation-resolution errors.

§Examples

See ExpressionRestriction.

Source

pub fn parse_literal_pattern(&mut self) -> Result<DynSegment>

Parses one literal_pattern from the current token stream and returns the segment.

Unlike parse_str, this method does not require end-of-stream.

§Errors

Returns an error if the input does not contain a valid literal_pattern.

Source

pub fn parse_tokens(&mut self, tokens: TokenStreamIter) -> Result<DynSegment>

Parses a token stream into a [DynSegment].

Sets the token source, runs the expression grammar, and returns the segment on success.

§Errors

Returns an error if the input does not contain a valid CEL expression.

  • Complexity: O(n) in the number of tokens.
Source

pub fn parse_str(&mut self, s: &str) -> Result<DynSegment>

Parses a string into a [DynSegment].

Tokenizes the string then parses; equivalent to parse_tokens(TokenStream::from_str(s)?.into_iter()).

§Errors

Returns an error on lex failure or if the input does not contain a valid CEL expression.

  • Complexity: O(n) in the length of s.
Source§

impl Parser<AstContext>

Source

pub fn parse_expression_ast(&mut self) -> Result<Expr>

Parses one expression from the current token stream and returns the built Expr.

Unlike parse_str_ast, this method does not require end-of-stream, allowing adam-lang to parse an expression embedded within a larger token stream.

§Errors

Returns an error if the input does not contain a valid expression.

  • Complexity: O(n) in the number of tokens in the expression.
Source

pub fn parse_tokens_ast(&mut self, tokens: TokenStreamIter) -> Result<Expr>

Parses a token stream into an Expr tree.

Sets the token source, runs the expression grammar, and returns the tree on success.

§Errors

Returns an error if the input does not contain a valid CEL expression.

  • Complexity: O(n) in the number of tokens.
Source

pub fn parse_str_ast(&mut self, s: &str) -> Result<Expr>

Parses a string into an Expr tree.

Tokenizes the string then parses; equivalent to parse_tokens_ast(TokenStream::from_str(s)?.into_iter()).

§Errors

Returns an error on lex failure or if the input does not contain a valid CEL expression.

  • Complexity: O(n) in the length of s.
§Examples
use cel_parser::{AstContext, Expr, OpLookup, Parser};

let mut parser = Parser::<AstContext>::new(OpLookup::new());
let expr = parser.parse_str_ast("1 + 2").unwrap();
assert!(matches!(expr, Expr::Op { .. }));

Auto Trait Implementations§

§

impl<C> !RefUnwindSafe for Parser<C>

§

impl<C> !Send for Parser<C>

§

impl<C> !Sync for Parser<C>

§

impl<C> !UnwindSafe for Parser<C>

§

impl<C> Freeze for Parser<C>
where C: Freeze,

§

impl<C> Unpin for Parser<C>
where C: Unpin,

§

impl<C> UnsafeUnpin for Parser<C>
where C: UnsafeUnpin,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.