бизон: одна ошибка вызывает дополнительную, но неверную ошибку - PullRequest
1 голос
/ 20 ноября 2010

В разделе класса моего кода, если я напишу ошибку, несколько строк будут сообщены как ошибки, когда они не должны.Я помещаю '| error' в определенные места, где можно исправлять ошибки / ошибки, но я не думаю, что они используются.Может, он пытается где-то возобновить среднюю экспрессию?

Есть ли способ заставить Бизона попытаться восстановиться в определенных местах?Как это работает и что я могу делать неправильно?

Я поместил строку ошибки рядом с циклом.Вот пример:

SomeRuleLoop:
    | Rule ',' SomeRuleLoop
Rule:
      A
    | B
    | C
    | Error
A:
      AA AAB AABC
    | AA AAB AABC Z
...

Вот пример моих правил.Я вижу "funcBody error" в моей консоли, однако следующая строка получает ошибку из-за первой ошибки.Несмотря на то, что каждый funcBodyRule является автономным.

funcBodyLoop:
    | funcBodyLoop funcBody

funcBody:
      funcBodyRule
    | error { printf("funcBody error"); $$=0; }
    | '#' EQ { printf("still in funcBody\n"); $$=0; }

Я попытался написать # == между строкой с первой ошибкой и строкой со 2-й.Я написал это, чтобы проверить, находится ли анализатор в цикле funcbody. Это не выдает ошибку, поэтому .Не говоря уже о том, что я добавил printf, и строка не печатается, так что, может быть, ее больше нет в цикле функций?как я могу это исправить?

Ответы [ 2 ]

1 голос
/ 20 ноября 2010

Yacc и Bison обычно используют леворекурсивные правила, и показанные правила не являются леворекурсивными.

Как показано, первое правило эквивалентно:

SomeRuleLoop:
        /* Nothing */
    |   Rule ',' SomeRuleLoop
    ;

Это праворекурсивное правило, которое говорит, что SomeRuleLoop - это либо пустая строка токенов, либо «Правило», за которым следует запятая и еще несколько SomeRuleLoop. Обратите внимание, что это означает, что SomeRuleLoop заканчивается запятой, что, вероятно, не то, что вы имели в виду.

Первое правило, вероятно, должно читаться следующим образом:

SomeRuleLoop:
        Rule
    |   SomeRuleLoop ',' Rule
    ;

Обратите внимание, что важно учитывать пустые альтернативы, но добавление их везде приводит к неоднозначности грамматики (больше конфликтов сдвига / уменьшения)


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

Тем не менее, я не уверен, каковы остальные ваши проблемы ...

0 голосов
/ 09 февраля 2011

Форсирование ';' или перевод строки в конце ошибки решает ее. (| error my_end_of_statenent вместо | error)

...