Посмотрите на файл y.output, созданный yacc или bison с аргументом -v. Первый конфликт в состоянии 5:
State 5
7 exp: NAME . '(' ')'
8 | NAME . '(' exp ')'
9 | NAME . '(' exp ',' exp ')'
10 | NAME . '=' exp
11 | NAME .
'=' shift, and go to state 14
'(' shift, and go to state 15
'(' [reduce using rule 11 (exp)]
$default reduce using rule 11 (exp)
В этом случае конфликт возникает, когда после NAME
стоит '('
- это неоднозначность в вашей грамматике, в которой это может быть выражение вызова или простое выражение NAME
, за которым следует выражение в скобках, потому что у вас нет разделителя между операторами на вашем языке.
Второй конфликт:
State 13
4 statment: exp .
17 exp: exp . '+' exp
18 | exp . '-' exp
19 | exp . '*' exp
20 | exp . '/' exp
21 | exp . '%' exp
22 | exp . '^' exp
23 | exp . '&' exp
24 | exp . '|' exp
25 | exp . 'x' exp
'+' shift, and go to state 21
'-' shift, and go to state 22
'*' shift, and go to state 23
'/' shift, and go to state 24
'%' shift, and go to state 25
'&' shift, and go to state 26
'|' shift, and go to state 27
'x' shift, and go to state 28
'^' shift, and go to state 29
'-' [reduce using rule 4 (statment)]
$default reduce using rule 4 (statment)
, что по сути та же проблема, на этот раз с '-'
- вход NAME - NAME
может быть одним двоичным оператором вычитания, или это может быть два оператора - ИМЯ, за которым следует унарный отрицательный знак.
Если вы добавите разделитель между операторами (например, ;
), оба этих конфликта исчезнут.