Как убрать смещение / уменьшение предупреждения?
Я пытаюсь сделать компилятор, и я сейчас пытаюсь сделать парсер. Я получаю предупреждение об этом состоянии: государство 89
62 expr: '(' expr . ')'
66 | expr . '+' expr
67 | expr . '-' expr
68 | expr . '*' expr
69 | expr . '/' expr
70 | expr . '%' expr
74 | expr . '&' expr
75 | expr . '|' expr
77 cond: expr .
78 | '(' expr . ')'
82 | expr . '=' expr
83 | expr . "<>" expr
84 | expr . '<' expr
85 | expr . '>' expr
86 | expr . ">=" expr
87 | expr . "<=" expr
"<>" shift, and go to state 91
">=" shift, and go to state 92
"<=" shift, and go to state 93
'+' shift, and go to state 94
'-' shift, and go to state 95
'|' shift, and go to state 96
'*' shift, and go to state 97
'/' shift, and go to state 98
'%' shift, and go to state 99
'&' shift, and go to state 100
'=' shift, and go to state 101
'<' shift, and go to state 102
'>' shift, and go to state 103
')' shift, and go to state 119
$default reduce using rule 77 (cond)
State 119
62 expr: '(' expr ')' .
78 cond: '(' expr ')' .
"and" reduce using rule 62 (expr)
"and" [reduce using rule 78 (cond)]
"or" reduce using rule 62 (expr)
"or" [reduce using rule 78 (cond)]
':' reduce using rule 62 (expr)
':' [reduce using rule 78 (cond)]
')' reduce using rule 62 (expr)
')' [reduce using rule 78 (cond)]
$default reduce using rule 62 (expr)
Моя грамматика для этой части:
expr:
T_const |
T_char_const |
l_value |
'(' expr ')' |
func_call |
'+' expr |
'-' expr |
expr '+' expr |
expr '-' expr |
expr '*' expr |
expr '/' expr |
expr '%' expr |
T_true | T_false |
'!' expr |
expr '&' expr |
expr '|' expr
;
cond:
'(' cond ')' |
expr |
T_not cond |
cond T_and cond |
cond T_or cond |
expr '=' expr |
expr T_not_equal expr |
expr '<' expr |
expr '>' expr |
expr T_greater_equal expr |
expr T_less_equal expr
;
В чем здесь проблема и как я могу ее исправить? Я уже исправил некоторые проблемы смещения / уменьшения, но в целом я не понимаю, что это за проблема. большое спасибо
1 ответ
Цитируемая вашим вопросом грамматика имеет вид:
cond: '(' cond ')'
Но тот, который указан в выходном файле, имеет вид:
cond: '(' expr ')'
Есть некоторые другие несоответствия, которые дают понять, что выходной файл не был сгенерирован из цитируемой грамматики. Это усложняет задачу ответа на ваш вопрос, хотя в корне проблема одинакова в обоих случаях. Я использую выходной файл в качестве ссылки для оставшейся части ответа.
Так как у вас также есть:
cond: expr
существует неопределенность в любом контексте, в котором cond
получает строку в скобках. (Конфликт, показанный для состояния 119, показывает это довольно четко.) Предположим, например, что парсер сталкивается
not ( x )
x
может быть уменьшено только до expr
(с помощью l_value
), но тут есть две возможности:
not ( expr ) => not expr [ from expr: ( expr ) ]
=> not cond [ from cond: expr ]
not ( expr ) => not cond [ from cond: ( eχpr ) ]
Эта двусмысленность существует во всех контекстах, где cond
позволено.
Разделить выражения синтаксически на логические и не логические выражения сложно и в большинстве случаев не нужно. Вы в конечном итоге разрешаете использовать любое выражение в качестве логического (cond: expr
), и вполне вероятно, что вы разрешите (или ваши пользователи ожидают, что вы позволите) логическое значение, которое будет присвоено переменной. Таким образом, самое простое и распространенное решение - просто сказать, что значение - это значение, а выражение - это выражение без логических выражений со специальным регистром.
Если вы действительно чувствуете необходимость синтаксически разделить их, вы найдете пример в этом недавнем вопросе.