summaryrefslogtreecommitdiffstats
path: root/discover
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2013-09-10 11:01:55 +0800
committerJeremy Kerr <jk@ozlabs.org>2013-09-24 13:14:59 +0800
commit0ac0cc8dbd8c3687880f3115ae41f9903e9f2333 (patch)
tree3459bc719b4a6378ebeb5698fed54318bb616d8f /discover
parent2817d0f575cd99bfc040e944e75aa2afd38597b7 (diff)
downloadtalos-petitboot-0ac0cc8dbd8c3687880f3115ae41f9903e9f2333.tar.gz
talos-petitboot-0ac0cc8dbd8c3687880f3115ae41f9903e9f2333.zip
discover/grub2: Initial grub2 lexer
Add a simple flex lexer to tokenise our grub2 config files. Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'discover')
-rw-r--r--discover/grub2/grub2.h10
-rw-r--r--discover/grub2/lexer.l127
-rw-r--r--discover/grub2/parser.y49
3 files changed, 186 insertions, 0 deletions
diff --git a/discover/grub2/grub2.h b/discover/grub2/grub2.h
new file mode 100644
index 0000000..f2a780d
--- /dev/null
+++ b/discover/grub2/grub2.h
@@ -0,0 +1,10 @@
+#ifndef GRUB2_H
+#define GRUB2_H
+
+struct grub2_parser {
+ void *scanner;
+};
+
+
+#endif /* GRUB2_H */
+
diff --git a/discover/grub2/lexer.l b/discover/grub2/lexer.l
new file mode 100644
index 0000000..18d1667
--- /dev/null
+++ b/discover/grub2/lexer.l
@@ -0,0 +1,127 @@
+
+%{
+#include "parser.h"
+#include <talloc/talloc.h>
+%}
+
+%option nounput noinput
+%option warn
+%option noyywrap
+%option stack noyy_top_state
+%option reentrant
+%option bison-bridge
+%option noyyalloc noyyfree noyyrealloc
+%option extra-type="struct grub2_parser *"
+%option header-file="lexer.h"
+%option outfile="lexer.c"
+
+%x sqstring
+%x dqstring
+
+WORD [^{}|&$;<> \t\n'"]+
+VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
+
+%%
+
+ /* discard leading & trailing whitespace, but keep inter-word delimeters */
+^[ \t]+ ;
+[ \t]+$ ;
+[ \t]* return TOKEN_DELIM;
+
+ /* reserved words */
+"[[" return TOKEN_LDSQBRACKET;
+"]]" return TOKEN_RDSQBRACKET;
+"case" return TOKEN_CASE;
+"do" return TOKEN_DO;
+"done" return TOKEN_DONE;
+"elif" return TOKEN_ELIF;
+"esac" return TOKEN_ESAC;
+"fi" return TOKEN_FI;
+"for" return TOKEN_FOR;
+"function" return TOKEN_FUNCTION;
+"if" return TOKEN_IF;
+"in" return TOKEN_IN;
+"menuentry" return TOKEN_MENUENTRY;
+"select" return TOKEN_SELECT;
+"then" return TOKEN_THEN;
+"time" return TOKEN_TIME;
+"until" return TOKEN_UTIL;
+"while" return TOKEN_WHILE;
+
+ /* anything that's not a metachar: return as a plain word */
+{WORD} {
+ yylval->strval = talloc_strdup(yyscanner, yytext);
+ yylval->expand = 0;
+ return TOKEN_WORD;
+ }
+
+\${VARNAME} |
+\$\{{VARNAME}\} {
+ yylval->strval = talloc_strdup(yyscanner, yytext);
+ yylval->expand = 1;
+ yylval->split = 1;
+ return TOKEN_WORD;
+ }
+
+ /* single-quoted strings: return a single, non-expanded word token */
+\' {
+ yy_push_state(sqstring, yyscanner);
+ }
+<sqstring>\' {
+ yy_pop_state(yyscanner);
+ return TOKEN_WORD;
+ }
+<sqstring>[^']+ {
+ yylval->expand = 0;
+ yylval->split = 0;
+ yylval->strval = talloc_strdup(yyscanner, yytext);
+ }
+
+ /* double-quoted strings: return a single, expanded word token */
+\" {
+ yy_push_state(dqstring, yyscanner);
+ }
+<dqstring>\" {
+ yy_pop_state(yyscanner);
+ return TOKEN_WORD;
+ }
+<dqstring>([^"]|\\\")+ {
+ yylval->expand = 1;
+ yylval->split = 0;
+ yylval->strval = talloc_strdup(yyscanner, yytext);
+ }
+
+
+ /* blocks */
+"{" return '{';
+"}" return '}';
+
+ /* end-of-line */
+[ \t]*(;|\n)[ \t]* return TOKEN_EOL;
+
+ /* strip comments */
+#.*$ ;
+
+
+. printf("unknown token '%s'\n", yytext); exit(1);
+
+%%
+
+struct grub2_parser;
+
+void *yyalloc(size_t bytes, void *yyscanner)
+{
+ struct grub2_parser *parser = yyget_extra(yyscanner);
+ return talloc_size(parser, bytes);
+}
+
+void *yyrealloc(void *ptr, size_t bytes, void *yyscanner)
+{
+ struct grub2_parser *parser = yyget_extra(yyscanner);
+ return talloc_realloc_size(parser, ptr, bytes);
+}
+
+void yyfree(void *ptr, void *yyscanner __attribute__((unused)))
+{
+ talloc_free(ptr);
+}
diff --git a/discover/grub2/parser.y b/discover/grub2/parser.y
new file mode 100644
index 0000000..2af2132
--- /dev/null
+++ b/discover/grub2/parser.y
@@ -0,0 +1,49 @@
+
+%pure-parser
+%lex-param { yyscan_t scanner }
+%parse-param { struct grub2_parser *parser }
+
+%{
+#include "lexer.h"
+%}
+
+%union {
+ struct {
+ char *strval;
+ int expand;
+ int split;
+ };
+}
+
+/* reserved words */
+%token TOKEN_LDSQBRACKET "[["
+%token TOKEN_RDSQBRACKET "]]"
+%token TOKEN_CASE "case"
+%token TOKEN_DO "do"
+%token TOKEN_DONE "done"
+%token TOKEN_ELIF "elif"
+%token TOKEN_ESAC "esac"
+%token TOKEN_FI "fi"
+%token TOKEN_FOR "for"
+%token TOKEN_FUNCTION "function"
+%token TOKEN_IF "if"
+%token TOKEN_IN "in"
+%token TOKEN_MENUENTRY "menuentry"
+%token TOKEN_SELECT "select"
+%token TOKEN_THEN "then"
+%token TOKEN_TIME "time"
+%token TOKEN_UTIL "until"
+%token TOKEN_WHILE "while"
+
+/* syntax */
+%token TOKEN_EOL
+%token TOKEN_DELIM
+%token TOKEN_WORD
+
+%start script
+
+%%
+
+script: /* empty */
+
+%%
OpenPOWER on IntegriCloud