Next: Compiler Requirements, Previous: GLR Semantic Actions, Up: GLR Parsers [Contents][Index]
In addition to the %dprec
and %merge
directives,
GLR parsers
allow you to reject parses on the basis of arbitrary computations executed
in user code, without having Bison treat this rejection as an error
if there are alternative parses. (This feature is experimental and may
evolve. We welcome user feedback.) For example,
widget: %?{ new_syntax } "widget" id new_args { $$ = f($3, $4); } | %?{ !new_syntax } "widget" id old_args { $$ = f($3, $4); } ;
is one way to allow the same parser to handle two different syntaxes for
widgets. The clause preceded by %?
is treated like an ordinary
action, except that its text is treated as an expression and is always
evaluated immediately (even when in nondeterministic mode). If the
expression yields 0 (false), the clause is treated as a syntax error,
which, in a nondeterministic parser, causes the stack in which it is reduced
to die. In a deterministic parser, it acts like YYERROR.
As the example shows, predicates otherwise look like semantic actions, and therefore you must be take them into account when determining the numbers to use for denoting the semantic values of right-hand side symbols. Predicate actions, however, have no defined value, and may not be given labels.
There is a subtle difference between semantic predicates and ordinary actions in nondeterministic mode, since the latter are deferred. For example, we could try to rewrite the previous example as
widget: { if (!new_syntax) YYERROR; } "widget" id new_args { $$ = f($3, $4); } | { if (new_syntax) YYERROR; } "widget" id old_args { $$ = f($3, $4); } ;
(reversing the sense of the predicate tests to cause an error when they are
false). However, this
does not have the same effect if new_args
and old_args
have overlapping syntax.
Since the mid-rule actions testing new_syntax
are deferred,
a GLR parser first encounters the unresolved ambiguous reduction
for cases where new_args
and old_args
recognize the same string
before performing the tests of new_syntax
. It therefore
reports an error.
Finally, be careful in writing predicates: deferred actions have not been evaluated, so that using them in a predicate will have undefined effects.
Next: Compiler Requirements, Previous: GLR Semantic Actions, Up: GLR Parsers [Contents][Index]