устранить грамматическую двусмысленность

Я опубликую правила рассматриваемой грамматики для начала.

interface_sections :  main_interface  bind_buttons  bind_functions bind_panel_items
                   ;  /* Components of a gui program */

bind_buttons       :  T_BEGIN  T_BIND  T_BUTTONS  T_SEMIC  component_list
                      T_END  T_BIND  T_BUTTONS  T_SEMIC 
                   |  epsilon
                   ;  /* Bind the buttons for GUI */

bind_functions     :  T_BEGIN  T_BIND  T_FUNCTIONS  T_SEMIC  component_list
                      T_END  T_BIND  T_FUNCTIONS  T_SEMIC 
                   |  epsilon
                   ;  /* Bind the graphical drawing functions for GUI */

bind_panel_items   :  T_BEGIN  T_BIND  T_PANEL  T_ITEMS  T_SEMIC  component_list
                      T_END  T_BIND  T_PANEL  T_ITEMS  T_SEMIC 
                   |  epsilon
                   ;  /* Bind the panel items or menus for GUI */

Обратите внимание, что если после main_interface компилятор увидит токен T_BEGIN, он не будет знать, к какому из правил привязки перейти. Это может означать запуск bind_buttons или это может означать, что вы хотите пропустить bind_buttons, а T_BEGIN означает запуск bind_functions.

Как я могу изменить эту грамматику, чтобы не было этой проблемы?

Требование: мне не разрешено добавлять/удалять терминалы. Я не могу сказать пользователю, что он должен изменить способ написания кода, я должен изменить правила, чтобы справиться с этим.

Я в тупике, есть идеи?

Обновление: interface_sections : main_interface bind_buttons bind_functions bind_panel_items ; /* Компоненты программы с графическим интерфейсом */

prefix_stuff       : T_BEGIN T_BIND

bind_buttons       :  prefix_stuff  T_BUTTONS  T_SEMIC  component_list
                      T_END  T_BIND  T_BUTTONS  T_SEMIC 
                   |  epsilon
                   ;  /* Bind the buttons for GUI */

bind_functions     :  prefix_stuff  T_FUNCTIONS  T_SEMIC  component_list
                      T_END  T_BIND  T_FUNCTIONS  T_SEMIC 
                   |  epsilon
                   ;  /* Bind the graphical drawing functions for GUI */

bind_panel_items   :  prefix_stuff  T_PANEL  T_ITEMS  T_SEMIC  component_list
                      T_END  T_BIND  T_PANEL  T_ITEMS  T_SEMIC 
                   |  epsilon
                   ;  /* Bind the panel items or menus for GUI */

Это дает мне те же ошибки сдвига/уменьшения при запуске через bison.

Тем не менее, я думаю, что это на правильном пути, я думаю, что мне нужно поместить T_BUTTONS, T_FUNCTIONS и T_PANEL в начало правила.

Дополнительная информация:

component_list     :  component_list  valid_components
                   |  valid_components
                   ;  /* For the four bind blocks - a list of components */

valid_components   :  dialog_box_spec
                   |  browser_box_spec
                   |  pull_down_or_right
                   ;  /* Possible components for the list */

person kralco626    schedule 03.11.2010    source источник
comment
Я начал редактировать свой ответ, но теперь мне любопытно - как вы думаете, почему здесь есть конфликты сдвига и уменьшения? Синтаксический анализатор представляет собой синтаксический анализатор сдвига-уменьшения, то есть он сдвигает токены в стек, а затем, если возможно, сводит к нетерминалу. Когда синтаксический анализатор увидит T_BEGIN, он будет вынужден сместиться, потому что он не может уменьшить. Похоже, вы мыслите сверху вниз.   -  person Kizaru    schedule 03.11.2010
comment
Я использую flex/bison для синтаксического анализа. Он говорит мне, что есть 2 ошибки уменьшения смены. В рамках задания мне также сказали, что есть 2 ошибки просеивания и уменьшения. Мне также сказали, что проблема связана с возможностью включения 0-3 из этих разделов привязки.   -  person kralco626    schedule 03.11.2010
comment
Я собираюсь попробовать переместить просто T-BEGIN T_BIND в правило prefix_stuff и посмотреть, что мне даст bison.   -  person kralco626    schedule 03.11.2010
comment
Облом, я только что внес изменения, и все еще есть 2 конфликта сдвига/уменьшения   -  person kralco626    schedule 03.11.2010
comment
Я думаю, мне нужно каким-то образом вывести T_Buttons, T_functions и T_Panel в начало правила.   -  person kralco626    schedule 03.11.2010
comment
Каково ваше правило component_list?   -  person Kizaru    schedule 03.11.2010
comment
component_list : component_list действительные_компоненты | действительные_компоненты; /* Для четырех блоков привязки — список компонентов / valid_components : dialog_box_spec | browser_box_spec | pull_down_or_right ; // Возможные компоненты для списка */ но я добавлю к вопросу, чтобы я мог отформатировать   -  person kralco626    schedule 03.11.2010


Ответы (1)


interface_sections :  main_interface  bind_sections_one
                   ;  /* Components of a gui program */

bind_sections_one  : epsilon | T_BEGIN T_BIND bind_first ;

bind_first         : T_BUTTONS T_SEMIC  component_list
                      T_END  T_BIND  T_BUTTONS  T_SEMIC bind_sections_two
                   |  T_FUNCTIONS T_SEMIC component_list T_END T_BIND T_FUNCTIONS T_SEMIC bind_sections_three | T_PANEL T_ITEMS T_SEMIC component_list T_END T_BIND T_PANEL T_ITEMS T_SEMIC
                   ;

bind_sections_two    : epsilon | T_BEGIN T_BIND bind_second ;

bind_second        : T_FUNCTIONS T_SEMIC component_list T_END T_BIND T_FUNCTIONS T_SEMIC bind_sections_three | T_PANEL T_ITEMS T_SEMIC component_list T_END T_BIND T_PANEL T_ITEMS T_SEMIC ;

bind_sections_three   : epsilon | T_BEGIN T_BIND bind_third;

bind_third        : T_PANEL T_ITEMS T_SEMIC component_list T_END T_BIND T_PANEL T_ITEMS T_SEMIC ;

Это не привело к ошибкам сдвига и уменьшения, и мне кажется, что это должно сработать.

Кто-нибудь видит проблему?

person kralco626    schedule 03.11.2010