Я пытаюсь реализовать грамматику, которая позволяет умножать путем сопоставления. Это для анализа полиномиальных входных данных для CAS.
Насколько мне известно, он работает довольно хорошо, за исключением нескольких крайних случаев. Я выделил две проблемы:
- Конфликт с другими правилами, например,
a^2 b
(ошибочно) интерпретируется как(^ a (* 2 b))
, а не как(* (^ a 2) b)
. - yacc(bison) сообщает
28 shift/reduce conflicts
и8 reduce/reduce conflicts
.
Я почти уверен, что правильное решение первой проблемы решит и вторую, но пока мне это не удалось.
Ниже приводится суть грамматики, с которой я работаю:
%start prgm
%union {
double num;
char *var;
ASTNode *node;
}
%token <num> NUM
%token <var> VAR
%type <node> expr
%left '+' '-'
%left '*' '/'
%right '^'
%%
prgm: // nothing
| prgm '\n'
| prgm expr '\n'
;
expr: NUM
| VAR
| expr '+' expr
| expr '-' expr
| expr '*' expr
| expr '/' expr
| expr '^' expr
| expr expr %prec '*'
| '-' expr
| '(' expr ')'
;
%%
Удаление правила сопоставления (expr expr %prec '*'
) устраняет предупреждения о сдвиге/уменьшении и уменьшении/уменьшении.
Обратите внимание, что ab
в моей грамматике должно означать (* a b)
. Перед многосимвольными переменными должна стоять кавычка ('
); это уже хорошо обработано в файле lex
. Лексер полностью игнорирует пробелы (
) и табуляции (\t
).
Мне известен этот вопрос, но использование сопоставления здесь, похоже, не указывает на умножение.
Любые комментарии или помощь будут очень признательны!
P.S. Если это поможет, это ссылка на весь проект.
expr
наexpr_sequence
и добавив новый нетерминалexpr_sequence: expr | expr_sequence expr
, который еще не потерпел неудачу. Не могли бы вы подробнее рассказать о том, где заменить моиexpr
наexpr_sequence
? - person Jay Lee   schedule 27.03.2021