Вопрос

Here is an excerpt from [filename].output state 94

   32 expr: expr . opt_at_type '.' TYPEID '(' opt_expr_list ')'
   39     | expr . '+' expr
   40     | expr . '-' expr
   41     | expr . '*' expr
   42     | expr . '/' expr
   42     | expr '/' expr .
   44     | expr . '<' expr
   45     | expr . LE expr
   46     | expr . '=' expr

    '@'  shift, and go to state 73

    '.'       reduce using rule 23 (opt_at_type)
    '.'       [reduce using rule 42 (expr)]
    $default  reduce using rule 42 (expr)

    opt_at_type  go to state 74

opt_at_type is defined as:

    opt_at_type:
            { $$ = idtable.add_string("SELF_TYPE"); }
            |       '@' TYPEID
            { $$ = $2;   }
            ;

and can you enlighten me why it is happening?

Это было полезно?

Решение

The problem you're running into is that yacc precedence levels are only taken into account to resolve shift/reduce conflicts, not reduce/reduce. In this case, the opt_at_type rule can match an empty string (it's optional), leading to a reduce/reduce conflict.

To fix it, you need to unfactor the rule to get rid of the epsilon production:

expr: expr '.' TYPEID '(' opt_expr_list ')'
    | expr '@' TYPEID '.' TYPEID '(' opt_expr_list ')'
    | expr '+' expr
       :

Without the epsilon production, it doesn't need an early reduce, so the conflict becomes a shift/reduce conflict which can be solved by yacc precedence normally.

Другие советы

When Bison sees the following:

expr '/' expr '.'

It doesn't know if this equates to:

1) expr opt_at_type '.'

OR

2) expr '/' expr opt_at_type '.'

For 1) it would reduce expr '/' expr to expr first and for 2) it would reduce /* Empty */ to opt_at_type first.

So we have discovered the ambiguity, to solve it you must determine what syntax you want. One solution would be to make the first expr rule a separate rule so that it could not be used inside the other expressions like so:

typeexpr: expr opt_at_type '.' TYPEID '(' opt_expr_list ')'
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top