]> git.ozlabs.org Git - petitboot/blobdiff - discover/grub2/lexer.l
discover/grub2: Initial grub2 lexer
[petitboot] / discover / grub2 / lexer.l
diff --git a/discover/grub2/lexer.l b/discover/grub2/lexer.l
new file mode 100644 (file)
index 0000000..18d1667
--- /dev/null
@@ -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);
+}