Я опубликую правила рассматриваемой грамматики для начала.
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 */