Как убрать смещение / уменьшение предупреждения?

Я пытаюсь сделать компилятор, и я сейчас пытаюсь сделать парсер. Я получаю предупреждение об этом состоянии: государство 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), и вполне вероятно, что вы разрешите (или ваши пользователи ожидают, что вы позволите) логическое значение, которое будет присвоено переменной. Таким образом, самое простое и распространенное решение - просто сказать, что значение - это значение, а выражение - это выражение без логических выражений со специальным регистром.

Если вы действительно чувствуете необходимость синтаксически разделить их, вы найдете пример в этом недавнем вопросе.

Другие вопросы по тегам