%token IF THEN ELSE ELIF FI CASE ESAC FOR SELECT WHILE UNTIL DO DONE FUNCTION %token COND_START COND_END COND_ERROR %token IN BANG TIME TIMEOPT %token WORD ASSIGNMENT_WORD %token NUMBER %token ARITH_CMD ARITH_FOR_EXPRS %token COND_CMD %token AND_AND OR_OR GREATER_GREATER LESS_LESS LESS_AND %token GREATER_AND SEMI_SEMI LESS_LESS_MINUS AND_GREATER LESS_GREATER %token GREATER_BAR %token yacc_EOF /* %type inputunit command pipeline pipeline_command %type list list0 list1 compound_list simple_list simple_list1 %type simple_command shell_command %type for_command select_command case_command group_command %type arith_command %type cond_command %type arith_for_command %type function_def function_body if_command elif_clause subshell %type redirection redirection_list %type simple_command_element %type word_list pattern %type pattern_list case_clause_sequence case_clause %type timespec */ %start inputunit /* %left '&' ';' '\n' yacc_EOF %left AND_AND OR_OR %right '|' */ %% inputunit: simple_list '\n' | '\n' | error '\n' | yacc_EOF ; word_list: WORD | word_list WORD ; redirection: '>' WORD | '<' WORD | NUMBER '>' WORD | NUMBER '<' WORD | GREATER_GREATER WORD | NUMBER GREATER_GREATER WORD | LESS_LESS WORD | NUMBER LESS_LESS WORD | LESS_AND NUMBER | NUMBER LESS_AND NUMBER | GREATER_AND NUMBER | NUMBER GREATER_AND NUMBER | LESS_AND WORD | NUMBER LESS_AND WORD | GREATER_AND WORD | NUMBER GREATER_AND WORD | LESS_LESS_MINUS WORD | NUMBER LESS_LESS_MINUS WORD | GREATER_AND '-' | NUMBER GREATER_AND '-' | LESS_AND '-' | NUMBER LESS_AND '-' | AND_GREATER WORD | NUMBER LESS_GREATER WORD | LESS_GREATER WORD | GREATER_BAR WORD | NUMBER GREATER_BAR WORD ; simple_command_element: WORD | ASSIGNMENT_WORD | redirection ; redirection_list: redirection | redirection_list redirection ; simple_command: simple_command_element | simple_command simple_command_element ; command: simple_command | shell_command | shell_command redirection_list | function_def ; shell_command: for_command | case_command | WHILE compound_list DO compound_list DONE | UNTIL compound_list DO compound_list DONE | select_command | if_command | subshell | group_command | arith_command | cond_command | arith_for_command ; for_command: FOR WORD newline_list DO compound_list DONE | FOR WORD newline_list '{' compound_list '}' | FOR WORD ';' newline_list DO compound_list DONE | FOR WORD ';' newline_list '{' compound_list '}' | FOR WORD newline_list IN word_list list_terminator newline_list DO compound_list DONE | FOR WORD newline_list IN word_list list_terminator newline_list '{' compound_list '}' ; arith_for_command: FOR ARITH_FOR_EXPRS list_terminator newline_list DO compound_list DONE | FOR ARITH_FOR_EXPRS list_terminator newline_list '{' compound_list '}' | FOR ARITH_FOR_EXPRS DO compound_list DONE | FOR ARITH_FOR_EXPRS '{' compound_list '}' ; select_command: SELECT WORD newline_list DO list DONE | SELECT WORD newline_list '{' list '}' | SELECT WORD ';' newline_list DO list DONE | SELECT WORD ';' newline_list '{' list '}' | SELECT WORD newline_list IN word_list list_terminator newline_list DO list DONE | SELECT WORD newline_list IN word_list list_terminator newline_list '{' list '}' ; case_command: CASE WORD newline_list IN newline_list ESAC | CASE WORD newline_list IN case_clause_sequence newline_list ESAC | CASE WORD newline_list IN case_clause ESAC ; function_def: WORD '(' ')' newline_list function_body | FUNCTION WORD newline_list '(' ')' newline_list function_body | FUNCTION WORD newline_list function_body ; function_body: shell_command | shell_command redirection_list ; subshell: '(' compound_list ')' ; if_command: IF compound_list THEN compound_list FI | IF compound_list THEN compound_list ELSE compound_list FI | IF compound_list THEN compound_list elif_clause FI ; group_command: '{' compound_list '}' ; arith_command: ARITH_CMD ; cond_command: COND_START COND_CMD COND_END ; elif_clause: ELIF compound_list THEN compound_list | ELIF compound_list THEN compound_list ELSE compound_list | ELIF compound_list THEN compound_list elif_clause ; case_clause: pattern_list | case_clause_sequence pattern_list ; pattern_list: newline_list pattern ')' compound_list | newline_list pattern ')' newline_list | newline_list '(' pattern ')' compound_list | newline_list '(' pattern ')' newline_list ; case_clause_sequence: pattern_list SEMI_SEMI | case_clause_sequence pattern_list SEMI_SEMI ; pattern: WORD | pattern '|' WORD ; list: newline_list list0 ; compound_list: list | newline_list list1 ; list0: list1 '\n' newline_list | list1 '&' newline_list | list1 ';' newline_list ; list1: list1 '&' newline_list list2 | list1 ';' newline_list list2 | list1 '\n' newline_list list2 | list2 ; list2: list2 AND_AND newline_list pipeline_command | list2 OR_OR newline_list pipeline_command | pipeline_command ; list_terminator:'\n' | ';' | yacc_EOF ; newline_list: | newline_list '\n' ; simple_list: simple_list1 | simple_list1 '&' | simple_list1 ';' ; simple_list1: simple_list1 '&' simple_list2 | simple_list1 ';' simple_list2 | simple_list2 ; simple_list2: simple_list2 AND_AND newline_list pipeline_command | simple_list2 OR_OR newline_list pipeline_command | pipeline_command ; pipeline_command: pipeline | BANG pipeline | timespec pipeline | timespec BANG pipeline | BANG timespec pipeline ; pipeline: command '|' newline_list pipeline | command ; timespec: TIME | TIME TIMEOPT ;