2016-04-07 2 views
1

У меня проблема с некоторыми моими правилами моей грамматики.GPPG-грамматика - правило никогда не будет использоваться

Грамматика как следующее:

defLINES : carrRet 
     | defLine carrRet 
     | defLines defLine carrRet 
     ; 

defLine : error carrRet        {yyerrok();} 
     | "DEF" kwType attrbt ID 
     | "DEF" kwType ID fieldSuff 
     ; 

kwType : "INT" 
     | "REAL" 
     ; 

fieldSuff: "[" expr "]" 
     | "[" expr "," expr "]" 
     ; 

attrbt : /* nothing */ 
     | "PHU" intValue 
     ; 

с входом для проверки:

DEF INT testvar1 
DEF REAL testvar2 

Для этого входа второе правило производства с головы «defLine» должен быть использован.

Почему? Третье правило будет использоваться всегда и выдает ошибку

Unexpected 'carRet', '[' expected. 

Спасибо большое за помощь, Alex

ответ

1

Это грамматика, конечно, получают по меньшей мере один конфликт сдвига/наряду с предупреждением о том, что производство attrbt: /* nothing */ является бесполезно из-за конфликта. (Если это не так, это связано с тем, что GPPG не предоставляет столько предупреждений, сколько бизонов. Но я уверен, что он по крайней мере допустит конфликт смены/уменьшения.)

Конфликт возникает в правилах:

defLine : "DEF" kwType attrbt ID 
defLine : "DEF" kwType ID fieldSuff 

потому что attrbt может быть пустым, но не может предшествовать ID во втором правиле. Предположим, что синтаксический анализатор столкнулся с DEF INT, а следующий символ - ID. На данный момент анализатор не знает, какая из двух производств для использования defLine, но разница имеет значение. В первом случае анализатор должен уменьшить пустой attrbt до смещения ID. Во втором случае создание attrbt было бы ошибкой.

Генераторы парсера Yacc-like всегда разрешают конфликты сдвига/уменьшения в пользу сдвига (если нет объявлений о приоритетах), поэтому в этом случае ID всегда будет сдвинут. Это означает, что невозможно сократить производство attrbt: /* nothing */. (Bison, по крайней мере, хотел бы предупредить вас об этом факте.

Кроме того, поскольку сдвиг ID будет происходить в этом случае только второе производство для defLine будет доступен, поэтому анализатор потребует fieldStuff следовать ID и fieldStuff должен начинаться с [. Отсюда возникает ошибка синтаксического анализа вы сталкиваетесь.

чтобы это исправить, необходимо удалить сдвиг/свертка конфликт. Один из простых способов было бы позволить attrbt в обоих defLine производств (вы можете обнаружить ошибка в семантическом действии). Еще одна возможность - удалить пустую продукцию для attrbt и явно разрешить ее не принимается:

attrbt : "PHU" intValue 

defLine : "DEF" kwType ID 
     | "DEF" kwType attrbt ID 
     | "DEF" kwType ID fieldSuff 
+0

Хорошо, спасибо вам за вашу большую помощь! Я решил решить проблему в семантическом Action и разрешить attrbt. Спасибо ... =) – Alex

Смежные вопросы