Shift/ уменьшить с равным приоритетом
Я должен построить компилятор для подмножества C. Очевидно, так как я впервые делаю такую вещь, она не очень хорошо работает. Тем не мение. В настоящее время я пытаюсь создать лексер и парсер для указанного подмножества.
Я решил собрать его по частям и исправлять ошибки по мере их появления. Итак, у меня есть базовая грамматика, как показано ниже. Эта грамматика анализирует правильно, и я могу сделать простую математику, включая операторы сравнения. Так как это подмножество C, и они возвращают целочисленные значения, это возможно.
Теперь самое сложное. Я также хочу (нужно) моделировать в !
а также -
в качестве унарных операторов значение -5 + 5 должно равняться 0.
Поскольку эти два унарных оператора связывают наиболее плотно, я полагаю, что мне нужно поместить их в условие термина моей грамматики. Поэтому я изменил свое условие термина на следующее:
term : NUMBER
| NOT term { printf("NOT term\n"); $$ = !$2; }
| SUB term { printf("MINUS term\n"); $$ = - ($2);}
| LEFTPAR exp RIGHTPAR { printf("expression between parents\n");$$ = $2; }
|
;
Однако это заставляет зубров жаловаться на ошибки сдвига / уменьшения. Я знаю основы того, как их исправить, однако это порождает сдвиг / уменьшение ошибок практически во всех возможных состояниях, поэтому я немного запутался в данный момент.
Я мог бы добавить больше приоритета в моей грамматике, выбрав -
над !
но они одинаково туго.
Вся грамматика
calclist : /* nothing */
| COMMENT { printf("Comment\n"); }
| calclist comp EOL { printf("= %d\n", $2); }
;
comp : exp
| comp GREATER exp { printf("comp GREATER factor\n");$$ = $1 > $3; }
| comp LESS exp { printf("comp LESS factor\n");$$ = $1 < $3; }
| comp EQUAL exp { printf("comp EQUAL factor\n");$$ = $1 == $3; }
| comp NEQUAL exp { printf("comp NEQUAL factor\n");$$ = $1 != $3; }
;
exp : factor
| exp ADD factor { printf("exp add factor\n");$$ = $1 + $3; }
| exp SUB factor { printf("exp sub factor\n");$$ = $1 - $3; }
;
factor : term
| factor MUL term { printf("factor mul term\n");$$ = $1 * $3; }
| factor DIV term { printf("factor div term\n");$$ = $1 / $3; }
;
term : NUMBER
| NOT term { printf("NOT term\n"); $$ = !$2; }
| SUB term { printf("MINUS term\n"); $$ = - ($2);}
| LEFTPAR exp RIGHTPAR { printf("expression between parents\n");$$ = $2; }
|
;
Вывод Bison следующий:
bison -dv bison.y
bison.y: conflicts: 12 shift/reduce
flex lex.l
cc -o calc bison.tab.c lex.yy.c -lfl
Я не собираюсь вставлять сюда весь файл bison.output, так как это довольно длинный файл.
Редактировать:
Вставленная ниже грамматика не содержит SUB
маркер. Добавил его, чтобы его можно было скопировать.
1 ответ
term : NUMBER
| NOT term { printf("NOT term\n"); $$ = !$2; }
| LEFTPAR exp RIGHTPAR { printf("expression between parents\n");$$ = $2; }
Проблема здесь, пустое производство. Просто удали это.
|
;