=== modified file 'ChangeLog' --- old/ChangeLog 2009-12-02 07:36:13 +0000 +++ new/ChangeLog 2009-12-06 15:50:49 +0000 @@ -1,3 +1,7 @@ +2009-12-06 BVK Chaitanya + + * script/parser.y: Bug fixes in grammar rules. + 2009-11-30 Robert Millan Fix $srcdir != $objdir build. === modified file 'script/parser.y' --- old/script/parser.y 2009-11-23 15:37:33 +0000 +++ new/script/parser.y 2009-12-06 12:20:01 +0000 @@ -21,10 +21,10 @@ #include #include -#define YYFREE grub_free -#define YYMALLOC grub_malloc +#define YYFREE grub_free +#define YYMALLOC grub_malloc #define YYLTYPE_IS_TRIVIAL 0 -#define YYENABLE_NLS 0 +#define YYENABLE_NLS 0 %} @@ -35,163 +35,185 @@ char *string; } -%token GRUB_PARSER_TOKEN_IF "if" -%token GRUB_PARSER_TOKEN_WHILE "while" -%token GRUB_PARSER_TOKEN_FUNCTION "function" -%token GRUB_PARSER_TOKEN_MENUENTRY "menuentry" -%token GRUB_PARSER_TOKEN_ELSE "else" -%token GRUB_PARSER_TOKEN_THEN "then" -%token GRUB_PARSER_TOKEN_FI "fi" +%token GRUB_PARSER_TOKEN_IF "if" +%token GRUB_PARSER_TOKEN_WHILE "while" +%token GRUB_PARSER_TOKEN_FUNCTION "function" +%token GRUB_PARSER_TOKEN_MENUENTRY "menuentry" +%token GRUB_PARSER_TOKEN_ELSE "else" +%token GRUB_PARSER_TOKEN_THEN "then" +%token GRUB_PARSER_TOKEN_FI "fi" +%token GRUB_PARSER_TOKEN_EOF 0 %token GRUB_PARSER_TOKEN_ARG -%type script_init script grubcmd command commands commandblock menuentry if -%type arguments; -%type GRUB_PARSER_TOKEN_ARG; + +%type GRUB_PARSER_TOKEN_IF +%type GRUB_PARSER_TOKEN_WHILE +%type GRUB_PARSER_TOKEN_FUNCTION +%type GRUB_PARSER_TOKEN_MENUENTRY +%type GRUB_PARSER_TOKEN_ELSE +%type GRUB_PARSER_TOKEN_THEN +%type GRUB_PARSER_TOKEN_FI +%type GRUB_PARSER_TOKEN_ARG + +%type argument arguments0 arguments1 + +%type script_init script grubcmd ifcmd command +%type commands1 menuentry statement %pure-parser -%lex-param { struct grub_parser_param *state }; +%error-verbose + +%lex-param { struct grub_parser_param *state }; %parse-param { struct grub_parser_param *state }; +%start script_init + %% /* It should be possible to do this in a clean way... */ -script_init: { state->err = 0; } script - { - state->parsed = $2; - } -; - -script: { $$ = 0; } - | '\n' { $$ = 0; } - | commands { $$ = $1; } - | function '\n' { $$ = 0; } - | menuentry '\n' { $$ = $1; } - | error - { - $$ = 0; - yyerror (state, "Incorrect command"); - state->err = 1; - yyerrok; - } -; - -delimiter: '\n' - | ';' - | delimiter '\n' -; - -newlines: /* Empty */ - | newlines '\n' -; - - - -arguments: GRUB_PARSER_TOKEN_ARG - { - $$ = grub_script_add_arglist (state, 0, $1); - } - | arguments GRUB_PARSER_TOKEN_ARG - { - $$ = grub_script_add_arglist (state, $1, $2); - } -; - -grubcmd: arguments - { - $$ = grub_script_create_cmdline (state, $1); - } +script_init: { state->err = 0; } script { state->parsed = $2; } +; + +script: /* Empty */ + { + $$ = 0; + } + | '\n' script + { + $$ = 0; + } + | statement delimiter script + { + struct grub_script_cmdblock *cmd; + cmd = (struct grub_script_cmdblock *) $3; + $$ = grub_script_add_cmd (state, cmd, $1); + } + | error + { + $$ = 0; + yyerror (state, "Incorrect command"); + yyerrok; + } +; + +newlines0: /* Empty */ | newlines1 ; +newlines1: newlines0 '\n' ; +delimiter: ';' | '\n' ; +delimiters: delimiter | delimiters '\n' ; + +statement: command { $$ = $1; } + | function { $$ = 0; } + | menuentry { $$ = $1; } +; + +argument: GRUB_PARSER_TOKEN_ARG { $$ = grub_script_add_arglist (state, 0, $1); } + | GRUB_PARSER_TOKEN_IF { $$ = grub_script_add_arglist (state, 0, $1); } + | GRUB_PARSER_TOKEN_ELSE { $$ = grub_script_add_arglist (state, 0, $1); } + | GRUB_PARSER_TOKEN_THEN { $$ = grub_script_add_arglist (state, 0, $1); } + | GRUB_PARSER_TOKEN_FI { $$ = grub_script_add_arglist (state, 0, $1); } + | GRUB_PARSER_TOKEN_WHILE { $$ = grub_script_add_arglist (state, 0, $1); } + | GRUB_PARSER_TOKEN_FUNCTION { $$ = grub_script_add_arglist (state, 0, $1); } + | GRUB_PARSER_TOKEN_MENUENTRY { $$ = grub_script_add_arglist (state, 0, $1); } +; + +arguments0: /* Empty */ { $$ = 0; } + | arguments1 { $$ = $1; } +; +arguments1: argument arguments0 + { + if ($2) + { + $1->next = $2; + $1->argcount += $2->argcount; + $2->argcount = 0; + } + $$ = $1; + } +; + +grubcmd: GRUB_PARSER_TOKEN_ARG arguments0 + { + struct grub_script_arglist *args; + args = grub_script_add_arglist (state, 0, $1); + if ($2) { + args->next = $2; + args->argcount += $2->argcount; + $2->argcount = 0; + } + $$ = grub_script_create_cmdline (state, args); + } ; /* A single command. */ -command: grubcmd delimiter { $$ = $1; } - | if delimiter { $$ = $1; } - | commandblock delimiter { $$ = $1; } -; - -/* A block of commands. */ -commands: command - { - $$ = grub_script_add_cmd (state, 0, $1); - } - | command commands - { - struct grub_script_cmdblock *cmd; - cmd = (struct grub_script_cmdblock *) $2; - $$ = grub_script_add_cmd (state, cmd, $1); - } -; - -/* A function. Carefully save the memory that is allocated. Don't - change any stuff because it might seem like a fun thing to do! - Special care was take to make sure the mid-rule actions are - executed on the right moment. So the `commands' rule should be - recognized after executing the `grub_script_mem_record; and before - `grub_script_mem_record_stop'. */ -function: "function" GRUB_PARSER_TOKEN_ARG - { - grub_script_lexer_ref (state->lexerstate); - } newlines '{' - { - /* The first part of the function was recognized. - Now start recording the memory usage to store - this function. */ - state->func_mem = grub_script_mem_record (state); - } newlines commands '}' - { - struct grub_script *script; - - /* All the memory usage for parsing this function - was recorded. */ - state->func_mem = grub_script_mem_record_stop (state, - state->func_mem); - script = grub_script_create ($8, state->func_mem); - if (script) - grub_script_function_create ($2, script); - grub_script_lexer_deref (state->lexerstate); - } -; - -/* Carefully designed, together with `menuentry' so everything happens - just in the expected order. */ -commandblock: '{' - { - grub_script_lexer_ref (state->lexerstate); - } - newlines commands '}' - { - grub_script_lexer_deref (state->lexerstate); - $$ = $4; - } -; - -/* A menu entry. Carefully save the memory that is allocated. */ -menuentry: "menuentry" - { - grub_script_lexer_ref (state->lexerstate); - } arguments newlines '{' - { - grub_script_lexer_record_start (state->lexerstate); - } newlines commands '}' - { - char *menu_entry; - menu_entry = grub_script_lexer_record_stop (state->lexerstate); - grub_script_lexer_deref (state->lexerstate); - $$ = grub_script_create_cmdmenu (state, $3, menu_entry, 0); - } -; - -/* The first part of the if statement. It's used to switch the lexer - to a state in which it demands more tokens. */ -if_statement: "if" { grub_script_lexer_ref (state->lexerstate); } -; - -/* The if statement. */ -if: if_statement commands "then" newlines commands "fi" - { - $$ = grub_script_create_cmdif (state, $2, $5, 0); - grub_script_lexer_deref (state->lexerstate); - } - | if_statement commands "then" newlines commands "else" newlines commands "fi" - { - $$ = grub_script_create_cmdif (state, $2, $5, $8); - grub_script_lexer_deref (state->lexerstate); - } +command: grubcmd { $$ = $1; } + | ifcmd { $$ = $1; } +; + +/* A list of commands. */ +commands1: newlines0 command + { + $$ = $2; + } + | commands1 delimiters command + { + struct grub_script_cmdblock *cmd; + cmd = (struct grub_script_cmdblock *) $3; + $$ = grub_script_add_cmd (state, cmd, $1); + } +; + +function: "function" GRUB_PARSER_TOKEN_ARG + { + grub_script_lexer_ref (state->lexerstate); + state->func_mem = grub_script_mem_record (state); + } + '{' commands1 delimiters '}' + { + struct grub_script *script; + state->func_mem = grub_script_mem_record_stop (state, + state->func_mem); + script = grub_script_create ($5, state->func_mem); + if (script) + grub_script_function_create ($2, script); + + grub_script_lexer_deref (state->lexerstate); + } +; + +menuentry: "menuentry" GRUB_PARSER_TOKEN_ARG + { + grub_script_lexer_ref (state->lexerstate); + } + arguments0 + { + grub_script_lexer_record_start (state->lexerstate); + } + '{' commands1 delimiters '}' + { + char *menu_entry; + struct grub_script_arglist *args; + + menu_entry = grub_script_lexer_record_stop (state->lexerstate); + grub_script_lexer_deref (state->lexerstate); + + args = grub_script_add_arglist (state, 0, $1); + if ($4) { + args->next = $4; + args->argcount += $4->argcount; + $4->argcount = 0; + } + $$ = grub_script_create_cmdmenu (state, args, menu_entry, 0); + } +; + +if: "if" { grub_script_lexer_ref (state->lexerstate); } +; +ifcmd: if commands1 delimiters "then" commands1 delimiters "fi" + { + $$ = grub_script_create_cmdif (state, $2, $5, 0); + grub_script_lexer_deref (state->lexerstate); + } + | if commands1 delimiters "then" commands1 delimiters "else" commands1 delimiters "fi" + { + $$ = grub_script_create_cmdif (state, $2, $5, $8); + grub_script_lexer_deref (state->lexerstate); + } ;