Expand description
Expression parser building blocks for creating operator precedence parsers.
This module provides generic types for building expression parsers with proper operator precedence and associativity. These are the fundamental building blocks that can be composed to create complete expression grammars.
§Expression Parser Types
InfixExpr(orNonAssocExpr) - Non-associative binary operators (e.g., comparison operators)PrefixExpr- Unary prefix operators (e.g.,-,!,*,&)PostfixExpr- Unary postfix operators (e.g.,?,!)LeftAssocExpr- Left-associative binary operators (e.g.,+,-,*,/)RightAssocExpr- Right-associative binary operators (e.g.,=,+=)
For complete examples of building expression parsers with proper precedence hierarchies, see the Expression Parsing section in the cookbook.
Left/Right associativity is not handled by the parser, we parse flat sequences. We only distinguish it here at parsing level for handing the AST structure to the later consumer.
§No Nesting Required
All expression types use a vector internally to store multiple operators or operands. This means you don’t need to nest expression types - the vec handles multiplicity:
- ✅
PrefixExpr<Op, Operand>- Handles 0..MAX operators viaDelimitedVec(++x) - ✅
PostfixExpr<Operand, Op>- Handles 0..MAX operators viaDelimitedVec(x–) - ✅
LeftAssocExpr<Operand, Op>andRightAssocExpr<Operand, Op>- Handle 1..MAX operands viaDelimitedVec(1+2+3) - ❌
PrefixExpr<Op, PrefixExpr<Op, Operand>>- Redundant! Don’t nest these types.
Since we use vecs internally, Box is only needed for recursive expression grammars
(e.g., parenthesized expressions), not for handling multiple operators.
§Handling Parenthesized Expressions
Parenthesized expressions are not part of these building blocks. They need special handling in your grammar because they allow overriding operator precedence.
The user defines how to integrate parentheses by including them in their primary expression type.
§Examples
unsynn! {
// For simple binary operations (non-associative):
type SimpleBinary = NonAssocExpr<LiteralInteger, Plus>;
// For left-associative chains (unlimited by default):
type Addition = LeftAssocExpr<LiteralInteger, Plus>;
}
// Parse a simple addition
let mut tokens = "1 + 2".to_token_iter();
let expr: Addition = tokens.parse().unwrap();
assert_eq!(expr.len(), 2); // 2 operandsStructs§
- Left
Assoc Expr - Left-associative infix operator expression.
- Postfix
Expr - Postfix unary operator expression.
- Prefix
Expr - Prefix unary operator expression.
- Right
Assoc Expr - Right-associative infix operator expression.
Type Aliases§
- Infix
Expr - Generic infix operator expression.
- NonAssoc
Expr - Type alias for non-associative binary operators.