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; }

Проблема здесь, пустое производство. Просто удали это.

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