1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
%{
#include "grub2.h"
#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->word = create_word(yyget_extra(yyscanner), yytext,
false, false);
return TOKEN_WORD;
}
\${VARNAME} |
\$\{{VARNAME}\} {
yylval->word = create_word(yyget_extra(yyscanner), yytext,
true, true);
return TOKEN_WORD;
}
/* single-quoted strings: return a single, non-expanded word token */
\' {
yy_push_state(sqstring, yyscanner);
}
<sqstring>\' {
yy_pop_state(yyscanner);
}
<sqstring>[^']+ {
yylval->word = create_word(yyget_extra(yyscanner), yytext,
false, false);
return TOKEN_WORD;
}
/* double-quoted strings: return a single, expanded word token */
\" {
yy_push_state(dqstring, yyscanner);
}
<dqstring>\" {
yy_pop_state(yyscanner);
}
<dqstring>([^"]|\\\")+ {
yylval->word = create_word(yyget_extra(yyscanner), yytext,
true, false);
return TOKEN_WORD;
}
/* 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);
}
|