make the linux-ppc packags be in synch with other platforms
[tangerine.git] / arch / common / boot / grub2 / normal / parser.y
blobad0b5f7560ecf5c241434b31e9d345cc42bf2195
1 /* parser.y - The scripting parser. */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2005,2006,2007 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
21 #include <grub/script.h>
22 #include <grub/mm.h>
24 #define YYFREE grub_free
25 #define YYMALLOC grub_malloc
26 #define YYLTYPE_IS_TRIVIAL 0
30 %union {
31 struct grub_script_cmd *cmd;
32 struct grub_script_arglist *arglist;
33 struct grub_script_arg *arg;
34 char *string;
37 %token GRUB_PARSER_TOKEN_IF "if"
38 %token GRUB_PARSER_TOKEN_WHILE "while"
39 %token GRUB_PARSER_TOKEN_FUNCTION "function"
40 %token GRUB_PARSER_TOKEN_MENUENTRY "menuentry"
41 %token GRUB_PARSER_TOKEN_ELSE "else"
42 %token GRUB_PARSER_TOKEN_THEN "then"
43 %token GRUB_PARSER_TOKEN_FI "fi"
44 %token GRUB_PARSER_TOKEN_NAME
45 %token GRUB_PARSER_TOKEN_VAR
46 %type <cmd> script_init script grubcmd command commands commandblock menuentry if
47 %type <arglist> arguments;
48 %type <arg> argument;
49 %type <string> "if" "while" "function" "else" "then" "fi"
50 %type <string> text GRUB_PARSER_TOKEN_NAME GRUB_PARSER_TOKEN_VAR
52 %pure-parser
53 %lex-param { struct grub_parser_param *state };
54 %parse-param { struct grub_parser_param *state };
57 /* It should be possible to do this in a clean way... */
58 script_init: { state->err = 0} script
60 state->parsed = $2;
64 script: commands { $$ = $1; }
65 | function '\n' { $$ = 0; }
66 | menuentry '\n' { $$ = $1; }
69 delimiter: '\n'
70 | ';'
71 | delimiter '\n'
74 newlines: /* Empty */
75 | newlines '\n'
78 /* Some tokens are both used as token or as plain text. XXX: Add all
79 tokens without causing conflicts. */
80 text: GRUB_PARSER_TOKEN_NAME
82 $$ = $1;
84 | "if"
86 $$ = $1;
88 | "while"
90 $$ = $1;
94 /* An argument can consist of some static text mixed with variables,
95 for example: `foo${bar}baz'. */
96 argument: GRUB_PARSER_TOKEN_VAR
98 $$ = grub_script_arg_add (state, 0, GRUB_SCRIPT_ARG_TYPE_VAR, $1);
100 | text
102 $$ = grub_script_arg_add (state, 0, GRUB_SCRIPT_ARG_TYPE_STR, $1);
104 /* XXX: Currently disabled to simplify the parser. This should be
105 parsed by yet another parser for readability. */
106 /* | argument GRUB_PARSER_TOKEN_VAR */
107 /* { */
108 /* $$ = grub_script_arg_add ($1, GRUB_SCRIPT_ARG_TYPE_VAR, $2); */
109 /* } */
110 /* | argument text */
111 /* { */
112 /* $$ = grub_script_arg_add ($1, GRUB_SCRIPT_ARG_TYPE_STR, $2); */
113 /* } */
116 arguments: argument
118 $$ = grub_script_add_arglist (state, 0, $1);
120 | arguments argument
122 $$ = grub_script_add_arglist (state, $1, $2);
126 grubcmd: GRUB_PARSER_TOKEN_NAME arguments
128 $$ = grub_script_create_cmdline (state, $1, $2);
130 | GRUB_PARSER_TOKEN_NAME
132 $$ = grub_script_create_cmdline (state, $1, 0);
136 /* A single command. */
137 command: grubcmd delimiter { $$ = $1; }
138 | if delimiter { $$ = $1; }
139 | commandblock delimiter { $$ = $1; }
140 | error delimiter
142 $$ = 0;
143 yyerror (state, "Incorrect command");
144 state->err = 1;
145 yyerrok;
149 /* A block of commands. */
150 commands: command
152 $$ = grub_script_add_cmd (state, 0, $1);
154 | command commands
156 struct grub_script_cmdblock *cmd;
157 cmd = (struct grub_script_cmdblock *) $2;
158 $$ = grub_script_add_cmd (state, cmd, $1);
162 /* A function. Carefully save the memory that is allocated. Don't
163 change any stuff because it might seem like a fun thing to do!
164 Special care was take to make sure the mid-rule actions are
165 executed on the right moment. So the `commands' rule should be
166 recognized after executing the `grub_script_mem_record; and before
167 `grub_script_mem_record_stop'. */
168 function: "function" GRUB_PARSER_TOKEN_NAME
170 grub_script_lexer_ref (state->lexerstate);
171 } newlines '{'
173 /* The first part of the function was recognized.
174 Now start recording the memory usage to store
175 this function. */
176 state->func_mem = grub_script_mem_record (state);
177 } newlines commands '}'
179 struct grub_script *script;
181 /* All the memory usage for parsing this function
182 was recorded. */
183 state->func_mem = grub_script_mem_record_stop (state,
184 state->func_mem);
185 script = grub_script_create ($8, state->func_mem);
186 if (script)
187 grub_script_function_create ($2, script);
188 grub_script_lexer_deref (state->lexerstate);
192 /* Carefully designed, together with `menuentry' so everything happens
193 just in the expected order. */
194 commandblock: '{'
196 grub_script_lexer_ref (state->lexerstate);
198 newlines commands '}'
200 grub_script_lexer_deref (state->lexerstate);
201 $$ = $4;
205 /* A menu entry. Carefully save the memory that is allocated. */
206 menuentry: "menuentry" argument
208 grub_script_lexer_ref (state->lexerstate);
209 } newlines '{'
211 grub_script_lexer_record_start (state->lexerstate);
212 } newlines commands '}'
214 char *menu_entry;
215 menu_entry = grub_script_lexer_record_stop (state->lexerstate);
216 grub_script_lexer_deref (state->lexerstate);
217 $$ = grub_script_create_cmdmenu (state, $2, menu_entry, 0);
221 /* The first part of the if statement. It's used to switch the lexer
222 to a state in which it demands more tokens. */
223 if_statement: "if" { grub_script_lexer_ref (state->lexerstate); }
226 /* The if statement. */
227 if: if_statement commands "then" newlines commands "fi"
229 $$ = grub_script_create_cmdif (state, $2, $5, 0);
230 grub_script_lexer_deref (state->lexerstate);
232 | if_statement commands "then" newlines commands "else" newlines commands "fi"
234 $$ = grub_script_create_cmdif (state, $2, $5, $8);
235 grub_script_lexer_deref (state->lexerstate);