%left
, %right
or %nonassoc
. An example of a precedence rule is:
%left TOK_MUL TOK_ADD ;
All tokens specified in this way are given priorities from highest (most prefered) to lowest (lest prefered) in the order they are encountered in the spec file. The tokens are also assigned the designated associativity. Any production making use of these terminals inherits their associativity and precedence.
It is also possible to directly assign a precedence and an associativity
to a production. This is done by prefixing a right hand side of a
production with a %prec
operator.
For example, the following grammar has a
well known ambiguity:
Expr -> e ; Stmt -> IF Expr THEN Stmt ELSE Stmt | IF Expr THEN Stmt | s ;
For example IF e THEN s ELSE IF e THEN s ELSE s
can be parsed
either as IF e THEN s ELSE [IF e THEN s ELSE s]}
or
IF e THEN s ELSE [IF e THEN s] ELSE s
. We can specify that
the first Stmt
production has higher precedence than the second
by specifying two dummy precedences and referencing them from
the right hand sides:
%nonassoc LONG SHORT ; Stmt -> %prec(LONG) IF Expr THEN Stmt ELSE Stmt | %prec(SHORT) IF Expr THEN Stmt | s ; Expr -> e ;
The resulting parser has no ambiguities and prefers matching the longer statement whenever possible (binding the else statement to the nearest if statement). See exampmles/test3.py for a complete example.
See the PyGgy Home Page.