summaryrefslogtreecommitdiffstats
path: root/discover/grub2/lexer.l
blob: 64eee279a3d0f3311c5c3cfe9770dfb5bd69797d (plain)
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);
}
OpenPOWER on IntegriCloud