I started writing a simple LR(1) parser with Bison. When processing lists I used a simple implementation of a vector, for example when parsing a list of expressions:
tuple-expression-list: expression[first] ',' expression[second] {
foo_vector_init(&$$);
foo_vector_push_back(&$$, $first);
foo_vector_push_back(&$$, $second); }
tuple-expression-list: tuple-expression-list[list] ',' expression[expr] {
foo_vector_push_back(&$list, $expr); $$ = $list; }
This worked fine. But then the grammar changed and I had to go for the GLR parser. Suddenly the compiler complained about $list
being constant. I found that for GLR parsers:
- when the parser splits actions are recorded and not executed until either:
- all but one parsers have died
- two parsers are merged
- One should never modify
yyval
in an action (which is the lookahead).
Questions:
- when I never have to merge am I sure that only the actions that result in the final parse are executed?
- Is assigning
$list
to a local variable first a valid fix or should I copy the vector deeply?