#include "grub2.h"
#include "parser.h"
#include <talloc/talloc.h>
+
+void yyerror(struct grub2_parser *parser, const char *fmt, ...);
%}
%option nounput noinput
+%option batch never-interactive
%option warn
%option noyywrap
%option stack noyy_top_state
%option reentrant
%option bison-bridge
+%option yylineno
%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'"]+
+WORD [^{}|&$;<> \t\n'"#]+
VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
%%
/* discard leading & trailing whitespace, but keep inter-word delimeters */
^[ \t]+ ;
[ \t]+$ ;
-[ \t]* return TOKEN_DELIM;
+[ \t]+ return TOKEN_DELIM;
/* reserved words */
"[[" return TOKEN_LDSQBRACKET;
"do" return TOKEN_DO;
"done" return TOKEN_DONE;
"elif" return TOKEN_ELIF;
+"else" return TOKEN_ELSE;
"esac" return TOKEN_ESAC;
"fi" return TOKEN_FI;
"for" return TOKEN_FOR;
"in" return TOKEN_IN;
"menuentry" return TOKEN_MENUENTRY;
"select" return TOKEN_SELECT;
+"submenu" return TOKEN_SUBMENU;
"then" return TOKEN_THEN;
"time" return TOKEN_TIME;
"until" return TOKEN_UTIL;
/* anything that's not a metachar: return as a plain word */
{WORD} {
- yylval->word = create_word(yyget_extra(yyscanner), yytext,
- false, false);
+ yylval->word = create_word_text(yyget_extra(yyscanner), yytext);
return TOKEN_WORD;
}
\${VARNAME} |
\$\{{VARNAME}\} {
- yylval->word = create_word(yyget_extra(yyscanner), yytext,
- true, true);
+ if (yytext[1] == '{') {
+ yytext[yyleng-1] = '\0';
+ yytext++;
+ }
+ yytext++;
+ yylval->word = create_word_var(yyget_extra(yyscanner), yytext,
+ true);
return TOKEN_WORD;
}
yy_pop_state(yyscanner);
}
<sqstring>[^']+ {
- yylval->word = create_word(yyget_extra(yyscanner), yytext,
- false, false);
+ yylval->word = create_word_text(yyget_extra(yyscanner), yytext);
return TOKEN_WORD;
}
<dqstring>\" {
yy_pop_state(yyscanner);
}
-<dqstring>([^"]|\\\")+ {
- yylval->word = create_word(yyget_extra(yyscanner), yytext,
- true, false);
+<dqstring>([^"\$]|\\\")+ {
+ yylval->word = create_word_text(yyget_extra(yyscanner), yytext);
+ return TOKEN_WORD;
+ }
+<dqstring>\${VARNAME} |
+<dqstring>\$\{{VARNAME}\} {
+ if (yytext[1] == '{') {
+ yytext[yyleng-1] = '\0';
+ yytext++;
+ }
+ yytext++;
+ yylval->word = create_word_var(yyget_extra(yyscanner), yytext,
+ false);
return TOKEN_WORD;
}
+
/* blocks */
"{" return '{';
"}" return '}';
[ \t]*(;|\n)[ \t]* return TOKEN_EOL;
/* strip comments */
-#.*$ ;
-
+#.* ;
-. printf("unknown token '%s'\n", yytext); exit(1);
+. {
+ yyerror(yyget_extra(yyscanner), "unknown token '%s'\n", yytext);
+ yyterminate();
+ }
%%