Join GitHub today
The Value Stack
During the rule execution phase your parser actions can make use of the “value stack” for organizing the construction of custom objects like AST nodes. The value stack is a simple stack construct that serves as temporary storage for custom objects.
Generally a rule can alter the value stack in any way it pleases. It can create new values and push them onto the stack, it can consume existing values, turn them into new values and push these, and so on. The parboiled parsing engine generally doesn’t care about how your rules and parser actions work with the stack.
There are two important exceptions though:
If a rule did not match for whatever reason the value stack is reset to the exact state it had before the execution of the failing rule was started. This means that failing rules cannot alter the value stack (this includes failing semantic predicate actions)!
The reason for this behavior is to enable you to place actions not only in the last position of a sequence of rules.
Consider this rule sequence:
Rule ← ‘a’ ‘b’ action ‘c’
Assume that the action run after matching ‘b’ pushes a new value onto the value stack.
If this rule sequence fails because its final element ‘c’ did not match the value stack would still contain the new value pushed by the action. Even though your rule logic might be able to deal with these cases this would greatly complicate action design and make the parser logic much more brittle.
The fact that parboiled resets the value stack in case of a rule mismatch enables you to place parser actions freely and use the value stack also for intra-Rule temporary storage, which can be really convenient in many scenarios.
Test and TestNot rules never affect the value stack. parboiled always resets the value stack back to a saved snapshot after a Test or TestNot rule has matched. You can therefore be sure that syntactic predicates will never “mess” with your value stack setup, even if they contain parser actions or reference other rules that do.