resolve grammar ambiguity
I'll post the rules of the grammar in question to start.
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 */
Notice that after main_interface if the compiler sees the token T_BEGIN it wont know which of the bind rules to go to. It could mean begin bind_buttons or it could mean you want to skip bind_buttons and the T_BEGIN is to start bind_functions.
How can I change this grammar to not have this issue?
Requirement: I am not allowed to add/remove terminals. I can't tell the user they have to change the way they write the code, I have to change the rules to handle it.
I'm stumped, any ideas?
Update: interface_sections : main_interface bind_buttons bind_functions bind_panel_items ; /* Components of a gui program */
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
开发者_Go百科 T_END T_BIND T_PANEL T_ITEMS T_SEMIC
| epsilon
; /* Bind the panel items or menus for GUI */
This gives me the same shift/reduce errors when running it through bison.
However, I think it's on the right track, I think I need to get the T_BUTTONS and T_FUNCTIONS and T_PANEL to the front of the rule
Additional info:
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 */
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 ;
This did not produce an shift-reduce errors and seems like it should work to me.
Anyone see an issue?
精彩评论