discover/grub2: Implement statement blocks
[petitboot] / discover / grub2 / parser.y
1
2 %pure-parser
3 %lex-param { yyscan_t scanner }
4 %parse-param { struct grub2_parser *parser }
5
6 %{
7 #include "grub2.h"
8 #include "parser.h"
9 #include "lexer.h"
10
11 #define YYLEX_PARAM parser->scanner
12
13 static void yyerror(struct grub2_parser *, char const *s);
14 %}
15
16 %union {
17         struct grub2_word       *word;
18         struct grub2_argv       *argv;
19         struct grub2_statement  *statement;
20         struct grub2_statements *statements;
21 }
22
23 /* reserved words */
24 %token  TOKEN_LDSQBRACKET       "[["
25 %token  TOKEN_RDSQBRACKET       "]]"
26 %token  TOKEN_CASE              "case"
27 %token  TOKEN_DO                "do"
28 %token  TOKEN_DONE              "done"
29 %token  TOKEN_ELIF              "elif"
30 %token  TOKEN_ESAC              "esac"
31 %token  TOKEN_FI                "fi"
32 %token  TOKEN_FOR               "for"
33 %token  TOKEN_FUNCTION          "function"
34 %token  TOKEN_IF                "if"
35 %token  TOKEN_IN                "in"
36 %token  TOKEN_MENUENTRY         "menuentry"
37 %token  TOKEN_SELECT            "select"
38 %token  TOKEN_THEN              "then"
39 %token  TOKEN_TIME              "time"
40 %token  TOKEN_UTIL              "until"
41 %token  TOKEN_WHILE             "while"
42
43 %type <statement>       statement
44 %type <statements>      statements
45 %type <argv>            words
46 %type <word>            word
47
48 /* syntax */
49 %token  TOKEN_EOL
50 %token  TOKEN_DELIM
51 %token  <word> TOKEN_WORD
52
53 %start  script
54 %debug
55
56 %%
57
58 script: statements {
59                 parser->statements = $1;
60         }
61
62 statements: statement {
63                 $$ = create_statements(parser);
64                 statement_append($$, $1);
65         }
66         | statements statement {
67                 statement_append($1, $2);
68         }
69
70 statement: TOKEN_EOL {
71                 $$ = NULL;
72         }
73         | words TOKEN_EOL {
74                    $$ = create_statement_simple(parser, $1);
75         }
76         | '{' statements '}' {
77                 $$ = create_statement_block(parser, $2);
78         }
79         | "if" TOKEN_DELIM statement
80                 "then" TOKEN_EOL
81                 statements
82                 "fi" TOKEN_EOL {
83                 $$ = create_statement_if(parser, $3, $6, NULL);
84         }
85         | "menuentry" TOKEN_DELIM words TOKEN_DELIM
86                 '{' statements '}'
87                 TOKEN_EOL {
88                 $$ = create_statement_menuentry(parser, $3, $6);
89         }
90
91 words:  word {
92                 $$ = create_argv(parser);
93                 argv_append($$, $1);
94         }
95         | words TOKEN_DELIM word {
96                 argv_append($1, $3);
97                 $$ = $1;
98         }
99
100 word:   TOKEN_WORD
101         | word TOKEN_WORD {
102                 word_append($1, $2);
103                 $$ = $1;
104         }
105
106 %%
107 void yyerror(struct grub2_parser *parser, char const *s)
108 {
109         fprintf(stderr, "%d: error: %s '%s'\n",
110                         yyget_lineno(parser->scanner),
111                         s, yyget_text(parser->scanner));
112 }