/* ------------------------------------------------------- The Grammar ------------------------------------------------------- */ /* * added tokens * Pipe '|' * Lparen '(' * Rparen ')' * Lessthan '<' * Greaterthan '<' * Ampersand '&' * Semicolon ';' */ %start_symbol complete_command %token_prefix TOKEN_ %token_type {struct token *} %extra_argument { struct parser_state *pstate } %include { #include "parser.h" #include } complete_command ::= list separator. complete_command ::= list. list ::= list separator_op and_or. list ::= and_or. and_or ::= pipeline. and_or ::= and_or AND_IF linebreak pipeline. and_or ::= and_or OR_IF linebreak pipeline. pipeline ::= pipe_sequence. pipeline ::= Bang pipe_sequence. pipe_sequence ::= command. pipe_sequence ::= pipe_sequence Pipe linebreak command. command ::= simple_command. command ::= compound_command. command ::= compound_command redirect_list. command ::= function_definition. compound_command ::= brace_group. compound_command ::= subshell. compound_command ::= for_clause. compound_command ::= case_clause. compound_command ::= if_clause. compound_command ::= while_clause. compound_command ::= until_clause. subshell ::= Lparen compound_list Rparen. compound_list ::= term. [NEWLINE] compound_list ::= newline_list term. [NEWLINE] compound_list ::= term separator. compound_list ::= newline_list term separator. term ::= term separator and_or. term ::= and_or. for_clause ::= For name linebreak do_group. for_clause ::= For name linebreak in sequential_sep do_group. for_clause ::= For name linebreak in wordlist sequential_sep do_group. name ::= NAME /* Apply rule 5 */. in ::= In /* Apply rule 6 */. /* TODO start looking for pattern = Esac here */ wordlist ::= wordlist WORD. wordlist ::= WORD. %fallback WORD NAME Esac In . case_clause ::= case_start case_list Esac. case_clause ::= case_start Esac. { pstate->incase = 0; } /* added to simplify */ case_start ::= Case WORD linebreak in linebreak. case_list ::= case_list case_item. case_list ::= case_item. %left NEWLINE. %right DSEMI. %right WORD. //%left WORD. case_item ::= case_item_ns . //case_item ::= case_item_ns DSEMI linebreak. case_item_ns ::= pattern Rparen linebreak. [DSEMI] case_item_ns ::= pattern Rparen linebreak DSEMI linebreak. case_item_ns ::= pattern Rparen compound_list linebreak. [DSEMI] case_item_ns ::= pattern Rparen compound_list linebreak DSEMI linebreak. //case_item_ns ::= Lparen pattern Rparen linebreak. [DSEMI] //case_item_ns ::= Lparen pattern Rparen compound_list linebreak. [DSEMI] //case_item_end ::= linebreak. //case_item_end ::= linebreak DSEMI linebreak. /* rule four implicitly done via %fallback */ pattern ::= WORD . /* Apply rule 4 */ pattern ::= pattern Pipe WORD . /* Do not apply rule 4 */ %ifdef CASE_NS case_clause ::= case_start case_list_ns Esac. case_list_ns ::= case_list case_item_ns. case_list_ns ::= case_item_ns. %endif if_clause ::= If compound_list Then compound_list else_part Fi. if_clause ::= If compound_list Then compound_list Fi. else_part ::= Elif compound_list Then compound_list. else_part ::= Elif compound_list Then compound_list else_part. else_part ::= Else compound_list. while_clause ::= While compound_list do_group. until_clause ::= Until compound_list do_group. //function_definition ::= fname Lparen Rparen linebreak function_body. function_definition ::= WORD Lparen Rparen linebreak function_body. function_body ::= compound_command /* Apply rule 9 */. function_body ::= compound_command redirect_list /* Apply rule 9 */. /* we would need two tokens of look-ahead to prove this should be a name * and not a word */ //fname ::= NAME /* Apply rule 8 */. //fname ::= WORD. brace_group ::= Lbrace compound_list Rbrace. do_group ::= Do compound_list Done /* Apply rule 6 */. simple_command ::= cmd_prefix cmd_word cmd_suffix. simple_command ::= cmd_prefix cmd_word. simple_command ::= cmd_prefix. simple_command ::= cmd_name cmd_suffix. simple_command ::= cmd_name. cmd_name ::= WORD /* Apply rule 7a */. cmd_word ::= WORD /* Apply rule 7b */. cmd_prefix ::= io_redirect. cmd_prefix ::= cmd_prefix io_redirect. cmd_prefix ::= ASSIGNMENT_WORD. cmd_prefix ::= cmd_prefix ASSIGNMENT_WORD. cmd_suffix ::= io_redirect. cmd_suffix ::= cmd_suffix io_redirect. cmd_suffix ::= WORD. cmd_suffix ::= cmd_suffix WORD. redirect_list ::= io_redirect. redirect_list ::= redirect_list io_redirect. io_redirect ::= io_file. io_redirect ::= IO_NUMBER io_file. io_redirect ::= io_here. io_redirect ::= IO_NUMBER io_here. io_file ::= Lessthan filename. io_file ::= LESSAND filename. io_file ::= Greaterthan filename. io_file ::= GREATAND filename. io_file ::= DGREAT filename. io_file ::= LESSGREAT filename. io_file ::= CLOBBER filename. filename ::= WORD /* Apply rule 2 */. io_here ::= DLESS here_end. io_here ::= DLESSDASH here_end. here_end ::= WORD /* Apply rule 3 */. newline_list ::= newline_list NEWLINE. newline_list ::= NEWLINE. { pstate->linebreak = 1; } linebreak ::= newline_list. [NEWLINE] linebreak ::= /* empty */. [NEWLINE] separator_op ::= Ampersand. separator_op ::= Semicolon. separator ::= separator_op linebreak. [NEWLINE] separator ::= newline_list. [NEWLINE] sequential_sep ::= Semicolon linebreak. sequential_sep ::= newline_list.