bison: една грешка причинява допълнителна, но неправилна грешка

В секцията клас на моя код, ако напиша грешка, няколко реда ще бъдат докладвани като грешки, когато не трябва. Поставям „| error“ на определени места, където е добре/безопасно да се възстановява от грешки, но не мисля, че го използва. Може би се опитва да възобнови средно изражение някъде?

Има ли начин да принудя Bison да се опита да се възстанови на определени места? Как работи и какво може да правя погрешно?

Сложих реда за грешка до цикъла. Ето един пример:

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

Опитах да напиша #== между реда с първата грешка и реда с втората. Написах това, за да проверя дали анализаторът все още е в цикъла funcbody. Това не дава грешка, така че е. Няма значение, добавих printf и низът не се отпечатва, така че може би вече не е във функционалния цикъл? как да поправя това?


person Community    schedule 19.11.2010    source източник
comment
Ще бъде почти невъзможно да помогнем много без някакъв код, който да ни помогне. Но трябва да е близо до минимален код, а не няколкостотин реда.   -  person Jonathan Leffler    schedule 20.11.2010
comment
@Jonathan Leffler: Това е мястото, където е цикълът. Модифицирах въпроса си   -  person    schedule 20.11.2010
comment
Знаете, че Yacc (Bison) е чувствителен към главни и малки букви, така че алтернативата с „Грешка“ не е същата като „грешка“ (което е „вградено“ и има специфично значение без възстановяване на грешки).   -  person Jonathan Leffler    schedule 20.11.2010
comment
@Jonathan Leffler: Добре отбелязано. Проверих и не използвам 'Error' никъде, само 'error'   -  person    schedule 20.11.2010
comment
Изпратете ми кода - вижте профила ми; Ще видя дали мога да разбера главата или опашката на проблема. Боя се, че фрагментът тук не е достатъчен, за да продължа.   -  person Jonathan Leffler    schedule 26.11.2010
comment
@Jonathan Leffler: Съкратената версия изглежда се справя добре с грешката. Ще напиша проблема до странност с конфликти за промяна/намаляване. Има ‹15 и кодът е @(a,b,c) с грешка на ')', което няма смисъл, защото @( се използва само като параметри с ')' в края. Ще приема проблема с конфликтите и ще го поправя друг ден   -  person    schedule 26.11.2010
comment
Добре - успех с разрешаването на проблема. Конфликтите могат да бъдат дразнещи.   -  person Jonathan Leffler    schedule 26.11.2010


Отговори (2)


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

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

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

Това е дясно-рекурсивно правило, което казва, че „SomeRuleLoop“ е или празен низ от токени, или „Правило“, последвано от запетая и още малко „SomeRuleLoop“. Обърнете внимание, че това означава, че „SomeRuleLoop“ завършва със запетая, което вероятно не е това, което сте имали предвид.

Първото правило вероятно трябва да гласи:

SomeRuleLoop:
        Rule
    |   SomeRuleLoop ',' Rule
    ;

Имайте предвид, че разрешаването на празни алтернативи е важно - но добавянето им навсякъде има тенденция да прави граматиката двусмислена (повече конфликти за преместване/намаляване)


Трябва също така да използвате токена „грешка“ (всички малки букви), а не „Грешка“ (смесен регистър), за да посочите точка, където може да възникне възстановяване на грешка.

Не съм сигурен обаче какви са останалите ви проблеми...

person Jonathan Leffler    schedule 20.11.2010
comment
Чакай чакай чакай... шегуваш се с мен. Ляво рекурсивно? НЕ правилно рекурсивно? Да, правя това погрешно. Това може да реши проблема с грешката. Ще коментирам, когато оправя всичко - person ; 20.11.2010
comment
Аз съм доста объркан. Промених правилата, за да останат рекурсивни. Виждам, че моето съобщение за грешка се отпечатва. И все пак получавам грешка. Актуализирах въпроса - person ; 26.11.2010

Принуждаване на ';' или нови редове в края на грешката я решават. (| error my_end_of_statenent вместо | error)

person Community    schedule 09.02.2011