pub struct CalcParserDriver<I> {
_marker: PhantomData<I>,
}Expand description
A driver that defines semantic actions for the calculator parser.
The CalcParserDriver type implements ParserDriver and acts as the
bridge between the parser engine (Parser) and calculator-specific
semantic logic.
It provides the behavior for grammar reductions and ambiguity resolution
during parsing. Each reduction corresponds to a grammar production rule
in ParData, and is responsible for building or evaluating partial
results (e.g., computing arithmetic expressions, populating the symbol
table), constructing AST, etc.
§Type Parameters
I: The input source (the lexer) that yieldsCalcTokens and maintains a contextualSymTab. Must implementTryNextWithContext<SymTab, Item = CalcToken>.
§Associated Types
ParserData = ParData: Generated parser metadata containing grammar rules, production IDs, and ambiguity identifiers.Token = CalcToken: The token type produced by the lexer and consumed by this parser.Parser = Parser<I, Self, SymTab>: The parser engine parameterized by this driver and context.Error = CalcError: Unified error type propagated during parsing.Context = SymTab: Externally supplied context.
§Responsibilities
The parser driver performs calculator-specific actions:
resolve_ambiguity— invoked when the grammar allows multiple valid interpretations of a token sequence. The driver chooses which parse path to follow by returning an appropriateParserAction.reduce— executed when a grammar production completes. The driver can perform semantic actions such as arithmetic evaluation, updating the symbol table, or producing intermediate values.
§Notes
- The driver may be stateless (
_markeronly), or store intermediate evaluation state if needed. - Ambiguities can be resolved dynamically based on the current parse state or the next lookahead token.
- The
reducemethod corresponds to grammar rules such as:allowing the driver to fold numerical operations or emit results or result nodes.Expr → Expr '+' Expr Expr → NUMBER
Fields§
§_marker: PhantomData<I>Marker to associate the driver with its input type I.
Trait Implementations§
Source§impl<I> ParserDriver for CalcParserDriver<I>
impl<I> ParserDriver for CalcParserDriver<I>
Source§type ParserData = ParData
type ParserData = ParData
Parser metadata generated from the calculator grammar.
Source§type Parser = Parser<I, CalcParserDriver<I>, <CalcParserDriver<I> as ParserDriver>::Context>
type Parser = Parser<I, CalcParserDriver<I>, <CalcParserDriver<I> as ParserDriver>::Context>
Concrete parser engine type.
Source§fn resolve_ambiguity(
&mut self,
_parser: &mut Self::Parser,
_context: &mut Self::Context,
ambig: <Self::ParserData as ParserData>::AmbigID,
token: &Self::Token,
) -> Result<ParserAction<StateID, ProdID, AmbigID>, ParlexError>
fn resolve_ambiguity( &mut self, _parser: &mut Self::Parser, _context: &mut Self::Context, ambig: <Self::ParserData as ParserData>::AmbigID, token: &Self::Token, ) -> Result<ParserAction<StateID, ProdID, AmbigID>, ParlexError>
Resolves grammar ambiguities when multiple parse actions are valid.
The driver can inspect the parser conflict (ambig) and the upcoming
token (token) to decide which parse branch to follow. This method
returns the selected ParserAction.
By default, most calculator grammars are unambiguous, so this method may simply return a default action or be left unimplemented.
§Shift/Reduce Conflicts
In practice, this hook is primarily used to resolve Shift/Reduce conflicts — cases where the parser can either:
- Reduce using a completed production rule, or
- Shift the next incoming token (
token).
Other types of conflicts (such as Reduce/Reduce) are much more difficult to handle programmatically and usually require modifying the grammar itself to eliminate ambiguity.
In a typical arithmetic grammar, you can use operator precedence and associativity to decide whether to shift or reduce. For example:
Expr -> Expr '+' ExprWhen the incoming token is *, the driver can compare the precedence
of '+' (lower) vs. '*' (higher) and decide to Shift, allowing
the parser to defer reduction until the higher-precedence operation
(*) is parsed first.
This strategy ensures that the resulting parse tree respects the intended operator precedence and associativity rules.
Source§fn reduce(
&mut self,
parser: &mut Self::Parser,
context: &mut Self::Context,
prod_id: <Self::ParserData as ParserData>::ProdID,
token: &Self::Token,
) -> Result<(), ParlexError>
fn reduce( &mut self, parser: &mut Self::Parser, context: &mut Self::Context, prod_id: <Self::ParserData as ParserData>::ProdID, token: &Self::Token, ) -> Result<(), ParlexError>
Performs semantic reduction for a completed grammar production.
This is the main hook for calculator logic: each time the parser
recognizes a rule (identified by prod_id), the driver can evaluate
or construct the corresponding result, possibly updating the context.
For example, when reducing:
Expr -> Expr '+' Exprthe driver may pop the right-hand values from the parser stack, perform addition, and push the result back.