]> git.ozlabs.org Git - petitboot/blob - discover/grub2/lexer.l
discover/grub2: Hook up flex/bison parser to discover server
[petitboot] / discover / grub2 / lexer.l
1
2 %{
3 #include "grub2.h"
4 #include "parser.h"
5 #include <talloc/talloc.h>
6 %}
7
8 %option nounput noinput
9 %option batch never-interactive
10 %option warn
11 %option noyywrap
12 %option stack noyy_top_state
13 %option reentrant
14 %option bison-bridge
15 %option noyyalloc noyyfree noyyrealloc
16 %option extra-type="struct grub2_parser *"
17 %option header-file="lexer.h"
18 %option outfile="lexer.c"
19
20 %x sqstring
21 %x dqstring
22
23 WORD    [^{}|&$;<> \t\n'"]+
24 VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
25
26 %%
27
28  /* discard leading & trailing whitespace, but keep inter-word delimeters */
29 ^[ \t]+ ;
30 [ \t]+$ ;
31 [ \t]*  return TOKEN_DELIM;
32
33  /* reserved words */
34 "[["         return TOKEN_LDSQBRACKET;
35 "]]"         return TOKEN_RDSQBRACKET;
36 "case"       return TOKEN_CASE;
37 "do"         return TOKEN_DO;
38 "done"       return TOKEN_DONE;
39 "elif"       return TOKEN_ELIF;
40 "esac"       return TOKEN_ESAC;
41 "fi"         return TOKEN_FI;
42 "for"        return TOKEN_FOR;
43 "function"   return TOKEN_FUNCTION;
44 "if"         return TOKEN_IF;
45 "in"         return TOKEN_IN;
46 "menuentry"  return TOKEN_MENUENTRY;
47 "select"     return TOKEN_SELECT;
48 "then"       return TOKEN_THEN;
49 "time"       return TOKEN_TIME;
50 "until"      return TOKEN_UTIL;
51 "while"      return TOKEN_WHILE;
52
53  /* anything that's not a metachar: return as a plain word */
54 {WORD}  {
55                 yylval->word = create_word_text(yyget_extra(yyscanner), yytext);
56                 return TOKEN_WORD;
57         }
58
59 \${VARNAME} |
60 \$\{{VARNAME}\} {
61                 if (yytext[1] == '{') {
62                         yytext[yyleng-1] = '\0';
63                         yytext++;
64                 }
65                 yytext++;
66                 yylval->word = create_word_var(yyget_extra(yyscanner), yytext,
67                                                 true);
68                 return TOKEN_WORD;
69         }
70
71  /* single-quoted strings: return a single, non-expanded word token */
72 \'      {
73                 yy_push_state(sqstring, yyscanner);
74         }
75 <sqstring>\' {
76                 yy_pop_state(yyscanner);
77         }
78 <sqstring>[^']+ {
79                 yylval->word = create_word_text(yyget_extra(yyscanner), yytext);
80                 return TOKEN_WORD;
81         }
82
83  /* double-quoted strings: return a single, expanded word token */
84 \"      {
85                 yy_push_state(dqstring, yyscanner);
86         }
87 <dqstring>\" {
88                 yy_pop_state(yyscanner);
89         }
90 <dqstring>([^"\$]|\\\")+ {
91                 yylval->word = create_word_text(yyget_extra(yyscanner), yytext);
92                 return TOKEN_WORD;
93         }
94 <dqstring>\${VARNAME} |
95 <dqstring>\$\{{VARNAME}\} {
96                 if (yytext[1] == '{') {
97                         yytext[yyleng-1] = '\0';
98                         yytext++;
99                 }
100                 yytext++;
101                 yylval->word = create_word_var(yyget_extra(yyscanner), yytext,
102                                                 false);
103                 return TOKEN_WORD;
104         }
105
106
107
108  /* blocks */
109 "{"     return '{';
110 "}"     return '}';
111
112  /* end-of-line */
113 [ \t]*(;|\n)[ \t]*      return TOKEN_EOL;
114
115  /* strip comments */
116 #.*$    ;
117
118
119 .       printf("unknown token '%s'\n", yytext); exit(1);
120
121 %%
122
123 struct grub2_parser;
124
125 void *yyalloc(size_t bytes, void *yyscanner)
126 {
127         struct grub2_parser *parser = yyget_extra(yyscanner);
128         return talloc_size(parser, bytes);
129 }
130
131 void *yyrealloc(void *ptr, size_t bytes, void *yyscanner)
132 {
133         struct grub2_parser *parser = yyget_extra(yyscanner);
134         return talloc_realloc_size(parser, ptr, bytes);
135 }
136
137 void yyfree(void *ptr, void *yyscanner __attribute__((unused)))
138 {
139         talloc_free(ptr);
140 }