2012-06-14 2 views
0

Я написал анализатор языка flex/bison prog. В настоящее время почти сделано (я полагал, что это было сделано, нужно только обработать синтаксические ошибки). В определенном классе возникает какая-то странная проблема.bison о предупреждениях о смене/уменьшении

Я верю, что проблема в парсере. Я остановился прочитать компиляции консоли и, сегодня, я вернулся к нему и увидел, плохо:

parser.y: conflicts: 801 shift/reduce, 237 reduce/reduce 

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

input: 
    | input expression { std::cout << $2; } 
    ; 

expression: 
     expression comparing expression { $$ = new AExpOperation($1, $2, $3); } 
    | expr2 { $$ = $1; } 
    | TNEW identifier TLBRACKET TRBRACKET { $$ = new AExpNewArray(NULL, $2); } 
    | TLPAREN expression TRPAREN { $$ = new AExpParent($2); } 
    ; 

expr2: 
     TPLUS expr2 { $$ = $2; } 
    | TMINUS expr2 { $$ = new AExpFastOp($2, $1, true); } 
    | TBNOT expr2 { $$ = new AExpFastOp($2, $1, true); } 
    | TNOT expr2 { $$ = new AExpFastOp($2, $1, true); } 
    | expr2 TINCREMENT { $$ = new AExpFastOp($1, $2, false); } 
    | TINCREMENT expr2 { $$ = new AExpFastOp($2, $1, true); } 
    | expr2 TDECREMENT { $$ = new AExpFastOp($1, $2, false); } 
    | TDECREMENT expr2 { $$ = new AExpFastOp($2, $1, true); } 
    ; 

comparing: 
     TEQ | TNE | TLT | TLE | TGT | TGE | TPLUS | TMINUS | TDIVIDE | TMULT | TOR | TAND 
    | TBXOR | TLSHIFT | TRSHIFT | TZFILL | TBOR | TBAND | TBNOT | TEQA | TNEA | TINSTANCEOF 
    ; 

identifier: 
     TNUMBER { $$ = new AExpression($1); } 
    | TNAME { $$ = new AExpression($1); } 
    | TSTRING { $$ = new AExpression($1); } 
    | TFALSE { $$ = new AExpression($1); } 
    | TTRUE { $$ = new AExpression($1); } 
    | TNULL { $$ = new AExpression($1); } 
    | TTHIS { $$ = new AExpression($1); } 
    ; 

Просто эта маленькая часть получила ошибки, которые я не понимаю, почему:

parser.y: warning: 1 useless nonterminal and 9 useless rules 
parser.y:40.25-29: warning: useless nonterminal: expr2 
parser.y:69.11-28: warning: useless rule: expression: expr2 
parser.y:75.11-34: warning: useless rule: expr2: TPLUS expr2 
parser.y:76.11-63: warning: useless rule: expr2: TMINUS expr2 
parser.y:77.11-62: warning: useless rule: expr2: TBNOT expr2 
parser.y:78.11-61: warning: useless rule: expr2: TNOT expr2 
parser.y:79.11-68: warning: useless rule: expr2: expr2 TINCREMENT 
parser.y:80.11-67: warning: useless rule: expr2: TINCREMENT expr2 
parser.y:81.11-68: warning: useless rule: expr2: expr2 TDECREMENT 
parser.y:82.11-67: warning: useless rule: expr2: TDECREMENT expr2 

Почему это говорит TPLUS expr2 бесполезно, к примеру?

Теперь мне интересно, насколько плохо сдвигаются/уменьшаются и уменьшаются/уменьшаются?

Ну, мне нужна подсказка.

+1

Для конфликтов смены/уменьшения, есть ли у вас объявления о приоритетах для ваших операторов? Если нет, вы получите огромное количество конфликтов сдвига/уменьшения, так как «бизон» не знает, что такое приоритет оператора. – templatetypedef

ответ

1

Вкратце, вы хотите разрешить конфликты смены/уменьшения и уменьшения/уменьшения. Конфликт - это способ генератора синтаксического анализа сказать, что он не знает, какое производство вы хотите применить, учитывая конкретный (неоднозначный) ввод.

Я думаю, что «бесполезно» - это способ бизона сказать, что нет возможного ввода, для которого могут применяться нетерминалы expr2.

Несколько замечаний о вашей грамматике: (1) У вашего выражения non-terminal, по-видимому, отсутствуют правила для identifier. То, как я читаю вашу грамматику, «a + 2» не является допустимым выражением. (2) Меня беспокоят отсутствие сепараторов высказываний - это не так, но я думаю, что вы представляете себе шансы на двусмысленность. Возможно, это ограничение языка, который вы разбираете.

Возможная стратегия для вас: временно удалить унарные функции оператора (expr2) и получить остальную работу синтаксического анализатора; затем добавить эту функцию обратно.

1

Сво говорит вам, что правило expr2 никогда не может быть уменьшена, потому что нет никакого производства для expr2, который не содержит рекурсивный expr2, что означает, что ни одна (конечная) вход никогда не может соответствовать a expr2.

Вы, вероятно, должны иметь производство expr2: identifier, добавляя, что предупреждения useless rule исчезнут, но все равно оставят некоторые изменения/уменьшены и уменьшены/конфликты, которые будут разрешены.