Я пишу небольшой парсер, который разбирает ограничения, используя Flex и Lemon. Лимон сообщает о нескольких конфликтах разбора, от которых мне не удалось избавиться. Существуют ли какие-либо особые приемы для избавления от разбора конфликтов в контексте свободной грамматики?Фиксация лимонного анализа confilcts
Грамматика заключается в следующем.
// Reprint of input file "Constraint_grammar.y".
// Symbols:
// 0 $ 5 NE 10 PLUS 15 NOT 20 error
// 1 IFF 6 GT 11 MINUS 16 LPAREN 21 constraint
// 2 AND 7 GTE 12 TIMES 17 RPAREN 22 bool_expr
// 3 OR 8 LT 13 DIVIDE 18 VARIABLE 23 int_expr
// 4 EQ 9 LTE 14 POWER 19 INTEGER
constraint ::= bool_expr.
bool_expr ::= LPAREN bool_expr RPAREN.
int_expr ::= LPAREN int_expr RPAREN.
bool_expr ::= int_expr LT int_expr.
bool_expr ::= int_expr GT int_expr.
bool_expr ::= int_expr EQ int_expr.
bool_expr ::= int_expr NE int_expr.
bool_expr ::= int_expr GTE int_expr.
bool_expr ::= int_expr LTE int_expr.
bool_expr ::= bool_expr AND bool_expr.
bool_expr ::= bool_expr OR bool_expr.
bool_expr ::= bool_expr IFF bool_expr.
int_expr ::= int_expr PLUS int_expr.
int_expr ::= int_expr MINUS int_expr.
int_expr ::= int_expr TIMES int_expr.
int_expr ::= int_expr DIVIDE int_expr.
int_expr ::= int_expr POWER int_expr.
bool_expr ::= NOT bool_expr.
int_expr ::= MINUS int_expr.
int_expr ::= VARIABLE.
bool_expr ::= VARIABLE.
int_expr ::= INTEGER.
%nonassoc IFF.
%left AND.
%left OR.
%nonassoc EQ NE GT GTE LT LTE.
%left PLUS MINUS.
%left TIMES DIVIDE.
%right POWER NOT.
%nonassoc LPAREN RPAREN.
ошибки следующим образом.
State 28:
(19) int_expr ::= VARIABLE *
(20) bool_expr ::= VARIABLE *
$ reduce 20
IFF reduce 20
AND reduce 20
OR reduce 20
EQ reduce 19
NE reduce 19
GT reduce 19
GTE reduce 19
LT reduce 19
LTE reduce 19
PLUS reduce 19
MINUS reduce 19
TIMES reduce 19
DIVIDE reduce 19
POWER reduce 19
RPAREN reduce 19
RPAREN reduce 20 ** Parsing conflict **
State 40:
bool_expr ::= bool_expr * AND bool_expr
bool_expr ::= bool_expr * OR bool_expr
bool_expr ::= bool_expr * IFF bool_expr
(11) bool_expr ::= bool_expr IFF bool_expr *
$ reduce 11
IFF shift 4
IFF reduce 11 ** Parsing conflict **
AND shift 1
OR shift 3
RPAREN reduce 11
Весь отчет парсер генератор здесь. http://pastebin.com/TRsV3WvK
Кто-нибудь знает, что я делаю неправильно здесь? Могу ли я игнорировать эти конфликты?
Я надеялся, что тип переменной может быть обнаружен по типу выражения, в котором он находился, но я думаю, что не могу этого сделать, не получив этот конфликт разбора. У меня был IFF как nonassoc, потому что я идиот и не понимал, что он ассоциативен. Думаю, я просто предположил, что это то же самое, что и эквалайзер. –
@Null Set: IFF больше похож на AND или OR, чем на EQ, я думаю. Проблему с типами переменных можно избежать, не имея как 'int_expr', так и' bool_expr' (используя единый 'expr') и определяя некоторую семантику для того, как целочисленное выражение обрабатывается в булевом контексте (например, как C делает с _0 - false, а не 0 - true_). Затем вы избавитесь от одного из двух правил expr: = LPAREN expr RPAREN.'. Но поскольку грамматика не может определить, является ли переменная логической или целочисленной, если вы не поможете ей, она не может определить, как обрабатывать «(переменную)», поскольку она может быть целым или логическим; это действительно двусмысленно. –
Имея явно введенные объявления переменных, вероятно, хорошая идея. Я вижу, что я всегда буду им в этом нуждаться. –