v2.7.0
Full Changelog: v2.6.0...v2.7.0
Resolving Ambiguities
In GLR parser, there can be both shift/reduce action possible at the same time, this leads to ambiguity of the grammar.
You can resolve the ambiguties through the reduce action.
- Returning
Result::Err(Error)
from the reduce action will revoke current reducing path. - Setting predefined variable
shift: &mut bool
tofalse
will revoke the shift action with lookahead token.
Consider the following example:
E : E plus E
| E star E
| digit
;
And you are trying to feed 1 + 2 * 3 + 4 eof
to the parser.
There are 5 ways to represent the input sequence:
((1 + 2) * 3) + 4
(1 + (2 * 3)) + 4
1 + ((2 * 3) + 4)
1 + (2 * (3 + 4))
(1 + 2) * (3 + 4)
However, we know the 2nd path is the only correct one,
since the star
has higher precedence than plus
, and both are left-associative.
To resolve the ambiguity, you can write the reduce action as follows:
E : E plus E {
match *lookahead {
'*' => {
// no reduce if the next token is '*'
// this prevent
// E + E / *
// ^ lookahead
// to be E * ...
// ^ (E + E)
return Err("".to_string());
}
_ => {
// revoke the shift action
// this prevent
// E + E / +
// ^ lookahead
// to be E + E + ...
// and enforce the reduced token takes place
// E + ...
// ^ (E + E)
*shift = false;
}
}
}
| E star E {
*shift = false;
}
| Number
;