X-Git-Url: https://pd.if.org/git/?a=blobdiff_plain;ds=sidebyside;f=utils%2Fsh%2Fgram.y;fp=utils%2Fsh%2Fgram.y;h=b3549ad9bc7cbb03ea6e419cb08b87cd337fba10;hb=dce1707cec7cd4268fe73371c7488052e5058181;hp=0000000000000000000000000000000000000000;hpb=5cd80baaa2b300ac0e2bded7bf9dfc7b74022ab8;p=pdutils diff --git a/utils/sh/gram.y b/utils/sh/gram.y new file mode 100644 index 0000000..b3549ad --- /dev/null +++ b/utils/sh/gram.y @@ -0,0 +1,202 @@ +/* ------------------------------------------------------- + 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.