discover/grub2: Implement reduce rules
authorJeremy Kerr <jk@ozlabs.org>
Wed, 11 Sep 2013 05:38:25 +0000 (13:38 +0800)
committerJeremy Kerr <jk@ozlabs.org>
Tue, 24 Sep 2013 05:14:59 +0000 (13:14 +0800)
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
discover/grub2/lexer.l
discover/grub2/parser.y

index 18d16672e59d4c07019cbcb3ce3d8215ca0fa2da..64eee279a3d0f3311c5c3cfe9770dfb5bd69797d 100644 (file)
@@ -1,5 +1,6 @@
 
 %{
 
 %{
+#include "grub2.h"
 #include "parser.h"
 #include <talloc/talloc.h>
 %}
 #include "parser.h"
 #include <talloc/talloc.h>
 %}
@@ -50,16 +51,15 @@ VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
 
  /* anything that's not a metachar: return as a plain word */
 {WORD} {
 
  /* anything that's not a metachar: return as a plain word */
 {WORD} {
-               yylval->strval = talloc_strdup(yyscanner, yytext);
-               yylval->expand = 0;
+               yylval->word = create_word(yyget_extra(yyscanner), yytext,
+                                               false, false);
                return TOKEN_WORD;
        }
 
 \${VARNAME} |
 \$\{{VARNAME}\} {
                return TOKEN_WORD;
        }
 
 \${VARNAME} |
 \$\{{VARNAME}\} {
-               yylval->strval = talloc_strdup(yyscanner, yytext);
-               yylval->expand = 1;
-               yylval->split = 1;
+               yylval->word = create_word(yyget_extra(yyscanner), yytext,
+                                               true, true);
                return TOKEN_WORD;
        }
 
                return TOKEN_WORD;
        }
 
@@ -69,12 +69,11 @@ VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
        }
 <sqstring>\' {
                yy_pop_state(yyscanner);
        }
 <sqstring>\' {
                yy_pop_state(yyscanner);
-               return TOKEN_WORD;
        }
 <sqstring>[^']+ {
        }
 <sqstring>[^']+ {
-               yylval->expand = 0;
-               yylval->split = 0;
-               yylval->strval = talloc_strdup(yyscanner, yytext);
+               yylval->word = create_word(yyget_extra(yyscanner), yytext,
+                                               false, false);
+               return TOKEN_WORD;
        }
 
  /* double-quoted strings: return a single, expanded word token */
        }
 
  /* double-quoted strings: return a single, expanded word token */
@@ -83,12 +82,11 @@ VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
        }
 <dqstring>\" {
                yy_pop_state(yyscanner);
        }
 <dqstring>\" {
                yy_pop_state(yyscanner);
-               return TOKEN_WORD;
        }
 <dqstring>([^"]|\\\")+ {
        }
 <dqstring>([^"]|\\\")+ {
-               yylval->expand = 1;
-               yylval->split = 0;
-               yylval->strval = talloc_strdup(yyscanner, yytext);
+               yylval->word = create_word(yyget_extra(yyscanner), yytext,
+                                               true, false);
+               return TOKEN_WORD;
        }
 
 
        }
 
 
index 45ad4e13127d4414d77db15412c4fe190d45dc80..a8c02e284b6d7b4507003839e1d5eb483814617f 100644 (file)
@@ -14,7 +14,10 @@ static void yyerror(struct grub2_parser *, char const *s);
 %}
 
 %union {
 %}
 
 %union {
-       struct grub2_word *word;
+       struct grub2_word       *word;
+       struct grub2_argv       *argv;
+       struct grub2_statement  *statement;
+       struct grub2_statements *statements;
 }
 
 /* reserved words */
 }
 
 /* reserved words */
@@ -37,42 +40,66 @@ static void yyerror(struct grub2_parser *, char const *s);
 %token TOKEN_UTIL              "until"
 %token TOKEN_WHILE             "while"
 
 %token TOKEN_UTIL              "until"
 %token TOKEN_WHILE             "while"
 
+%type <statement>      statement
+%type <statements>     statements
+%type <argv>           words
+%type <word>           word
+
 /* syntax */
 %token TOKEN_EOL
 %token TOKEN_DELIM
 /* syntax */
 %token TOKEN_EOL
 %token TOKEN_DELIM
-%token TOKEN_WORD
+%token <word> TOKEN_WORD
 
 %start script
 %debug
 
 %%
 
 
 %start script
 %debug
 
 %%
 
-script: statements
-       ;
+script: statements {
+               parser->statements = $1;
+       }
 
 
-statements: statement
-       | statements statement
-       ;
+statements: statement {
+               $$ = create_statements(parser);
+               statement_append($$, $1);
+       }
+       | statements statement {
+               statement_append($1, $2);
+       }
 
 
-statement: TOKEN_EOL
-       | words TOKEN_EOL
-       | '{' statements '}'
+statement: TOKEN_EOL {
+               $$ = NULL;
+       }
+       | words TOKEN_EOL {
+                  $$ = create_statement_simple(parser, $1);
+       }
+       | '{' statements '}' { $$ = NULL; }
        | "if" TOKEN_DELIM statement
                "then" TOKEN_EOL
                statements
        | "if" TOKEN_DELIM statement
                "then" TOKEN_EOL
                statements
-               "fi" TOKEN_EOL
+               "fi" TOKEN_EOL {
+               $$ = create_statement_if(parser, $3, $6, NULL);
+       }
        | "menuentry" TOKEN_DELIM words TOKEN_DELIM
                '{' statements '}'
        | "menuentry" TOKEN_DELIM words TOKEN_DELIM
                '{' statements '}'
-               TOKEN_EOL
-       ;
+               TOKEN_EOL {
+               $$ = create_statement_menuentry(parser, $3, $6);
+       }
 
 
-words: | word
-       | words TOKEN_DELIM word
-       ;
+words: word {
+               $$ = create_argv(parser);
+               argv_append($$, $1);
+       }
+       | words TOKEN_DELIM word {
+               argv_append($1, $3);
+               $$ = $1;
+       }
 
 word:  TOKEN_WORD
 
 word:  TOKEN_WORD
-       | word TOKEN_WORD
-       ;
+       | word TOKEN_WORD {
+               word_append($1, $2);
+               $$ = $1;
+       }
 
 %%
 void yyerror(struct grub2_parser *parser, char const *s)
 
 %%
 void yyerror(struct grub2_parser *parser, char const *s)