summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/parse/parse_c/bitbakeparser.l
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/parse/parse_c/bitbakeparser.l')
-rw-r--r--bitbake/lib/bb/parse/parse_c/bitbakeparser.l288
1 files changed, 288 insertions, 0 deletions
diff --git a/bitbake/lib/bb/parse/parse_c/bitbakeparser.l b/bitbake/lib/bb/parse/parse_c/bitbakeparser.l
new file mode 100644
index 0000000000..ee4ce14839
--- /dev/null
+++ b/bitbake/lib/bb/parse/parse_c/bitbakeparser.l
@@ -0,0 +1,288 @@
1/* bbf.flex
2
3 written by Marc Singer
4 6 January 2005
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
20
21 DESCRIPTION
22 -----------
23
24 flex lexer specification for a BitBake input file parser.
25
26 Unfortunately, flex doesn't welcome comments within the rule sets.
27 I say unfortunately because this lexer is unreasonably complex and
28 comments would make the code much easier to comprehend.
29
30 The BitBake grammar is not regular. In order to interpret all
31 of the available input files, the lexer maintains much state as it
32 parses. There are places where this lexer will emit tokens that
33 are invalid. The parser will tend to catch these.
34
35 The lexer requires C++ at the moment. The only reason for this has
36 to do with a very small amount of managed state. Producing a C
37 lexer should be a reasonably easy task as long as the %reentrant
38 option is used.
39
40
41 NOTES
42 -----
43
44 o RVALUES. There are three kinds of RVALUES. There are unquoted
45 values, double quote enclosed strings, and single quote
46 strings. Quoted strings may contain unescaped quotes (of either
47 type), *and* any type may span more than one line by using a
48 continuation '\' at the end of the line. This requires us to
49 recognize all types of values with a single expression.
50 Moreover, the only reason to quote a value is to include
51 trailing or leading whitespace. Whitespace within a value is
52 preserved, ugh.
53
54 o CLASSES. C_ patterns define classes. Classes ought not include
55 a repitition operator, instead letting the reference to the class
56 define the repitition count.
57
58 C_SS - symbol start
59 C_SB - symbol body
60 C_SP - whitespace
61
62*/
63
64%option never-interactive
65%option yylineno
66%option noyywrap
67%option reentrant stack
68
69
70%{
71
72#include "token.h"
73#include "lexer.h"
74#include <ctype.h>
75
76extern void *bbparseAlloc(void *(*mallocProc)(size_t));
77extern void bbparseFree(void *p, void (*freeProc)(void*));
78extern void *bbparseAlloc(void *(*mallocProc)(size_t));
79extern void *bbparse(void*, int, token_t, lex_t*);
80extern void bbparseTrace(FILE *TraceFILE, char *zTracePrompt);
81
82//static const char* rgbInput;
83//static size_t cbInput;
84
85
86int lineError;
87int errorParse;
88
89enum {
90 errorNone = 0,
91 errorUnexpectedInput,
92 errorUnsupportedFeature,
93};
94
95#define YY_EXTRA_TYPE lex_t*
96
97 /* Read from buffer */
98#define YY_INPUT(buf,result,max_size) \
99 { yyextra->input(buf, &result, max_size); }
100
101//#define YY_DECL static size_t yylex ()
102
103#define ERROR(e) \
104 do { lineError = yylineno; errorParse = e; yyterminate (); } while (0)
105
106static const char* fixup_escapes (const char* sz);
107
108%}
109
110
111C_SP [ \t]
112COMMENT #.*\n
113OP_ASSIGN "="
114OP_IMMEDIATE ":="
115OP_PREPEND "=+"
116OP_APPEND "+="
117OP_COND "?="
118B_OPEN "{"
119B_CLOSE "}"
120
121K_ADDTASK "addtask"
122K_ADDHANDLER "addhandler"
123K_AFTER "after"
124K_BEFORE "before"
125K_DEF "def"
126K_INCLUDE "include"
127K_INHERIT "inherit"
128K_PYTHON "python"
129K_FAKEROOT "fakeroot"
130K_EXPORT "export"
131K_EXPORT_FUNC "EXPORT_FUNCTIONS"
132
133STRING \"([^\n\r]|"\\\n")*\"
134SSTRING \'([^\n\r]|"\\\n")*\'
135VALUE ([^'" \t\n])|([^'" \t\n]([^\n]|(\\\n))*[^'" \t\n])
136
137C_SS [a-zA-Z_]
138C_SB [a-zA-Z0-9_+-.]
139REF $\{{C_SS}{C_SB}*\}
140SYMBOL {C_SS}{C_SB}*
141VARIABLE $?{C_SS}({C_SB}*|{REF})*(\[[a-zA-Z0-9_]*\])?
142FILENAME ([a-zA-Z_./]|{REF})(([-+a-zA-Z0-9_./]*)|{REF})*
143
144PROC \({C_SP}*\)
145
146%s S_DEF
147%s S_DEF_ARGS
148%s S_DEF_BODY
149%s S_FUNC
150%s S_INCLUDE
151%s S_INHERIT
152%s S_PROC
153%s S_RVALUE
154%s S_TASK
155
156%%
157
158{OP_APPEND} { BEGIN S_RVALUE;
159 yyextra->accept (T_OP_APPEND); }
160{OP_PREPEND} { BEGIN S_RVALUE;
161 yyextra->accept (T_OP_PREPEND); }
162{OP_IMMEDIATE} { BEGIN S_RVALUE;
163 yyextra->accept (T_OP_IMMEDIATE); }
164{OP_ASSIGN} { BEGIN S_RVALUE;
165 yyextra->accept (T_OP_ASSIGN); }
166{OP_COND} { BEGIN S_RVALUE;
167 yyextra->accept (T_OP_COND); }
168
169<S_RVALUE>\\\n{C_SP}* { }
170<S_RVALUE>{STRING} { BEGIN INITIAL;
171 size_t cb = yyleng;
172 while (cb && isspace (yytext[cb - 1]))
173 --cb;
174 yytext[cb - 1] = 0;
175 yyextra->accept (T_STRING, yytext + 1); }
176<S_RVALUE>{SSTRING} { BEGIN INITIAL;
177 size_t cb = yyleng;
178 while (cb && isspace (yytext[cb - 1]))
179 --cb;
180 yytext[cb - 1] = 0;
181 yyextra->accept (T_STRING, yytext + 1); }
182
183<S_RVALUE>{VALUE} { ERROR (errorUnexpectedInput); }
184<S_RVALUE>{C_SP}*\n+ { BEGIN INITIAL;
185 yyextra->accept (T_STRING, NULL); }
186
187{K_INCLUDE} { BEGIN S_INCLUDE;
188 yyextra->accept (T_INCLUDE); }
189{K_INHERIT} { BEGIN S_INHERIT;
190 yyextra->accept (T_INHERIT); }
191{K_ADDTASK} { BEGIN S_TASK;
192 yyextra->accept (T_ADDTASK); }
193{K_ADDHANDLER} { yyextra->accept (T_ADDHANDLER); }
194{K_EXPORT_FUNC} { BEGIN S_FUNC;
195 yyextra->accept (T_EXPORT_FUNC); }
196<S_TASK>{K_BEFORE} { yyextra->accept (T_BEFORE); }
197<S_TASK>{K_AFTER} { yyextra->accept (T_AFTER); }
198<INITIAL>{K_EXPORT} { yyextra->accept (T_EXPORT); }
199
200<INITIAL>{K_FAKEROOT} { yyextra->accept (T_FAKEROOT); }
201<INITIAL>{K_PYTHON} { yyextra->accept (T_PYTHON); }
202{PROC}{C_SP}*{B_OPEN}{C_SP}*\n* { BEGIN S_PROC;
203 yyextra->accept (T_PROC_OPEN); }
204<S_PROC>{B_CLOSE}{C_SP}*\n* { BEGIN INITIAL;
205 yyextra->accept (T_PROC_CLOSE); }
206<S_PROC>([^}][^\n]*)?\n* { yyextra->accept (T_PROC_BODY, yytext); }
207
208{K_DEF} { BEGIN S_DEF; }
209<S_DEF>{SYMBOL} { BEGIN S_DEF_ARGS;
210 yyextra->accept (T_SYMBOL, yytext); }
211<S_DEF_ARGS>[^\n:]*: { yyextra->accept (T_DEF_ARGS, yytext); }
212<S_DEF_ARGS>{C_SP}*\n { BEGIN S_DEF_BODY; }
213<S_DEF_BODY>{C_SP}+[^\n]*\n { yyextra->accept (T_DEF_BODY, yytext); }
214<S_DEF_BODY>\n { yyextra->accept (T_DEF_BODY, yytext); }
215<S_DEF_BODY>. { BEGIN INITIAL; unput (yytext[0]); }
216
217{COMMENT} { }
218
219<INITIAL>{SYMBOL} { yyextra->accept (T_SYMBOL, yytext); }
220<INITIAL>{VARIABLE} { yyextra->accept (T_VARIABLE, yytext); }
221
222<S_TASK>{SYMBOL} { yyextra->accept (T_TSYMBOL, yytext); }
223<S_FUNC>{SYMBOL} { yyextra->accept (T_FSYMBOL, yytext); }
224<S_INHERIT>{SYMBOL} { yyextra->accept (T_ISYMBOL, yytext); }
225<S_INCLUDE>{FILENAME} { BEGIN INITIAL;
226 yyextra->accept (T_ISYMBOL, yytext); }
227
228<S_TASK>\n { BEGIN INITIAL; }
229<S_FUNC>\n { BEGIN INITIAL; }
230<S_INHERIT>\n { BEGIN INITIAL; }
231
232[ \t\r\n] /* Insignificant whitespace */
233
234. { ERROR (errorUnexpectedInput); }
235
236 /* Check for premature termination */
237<<EOF>> { return T_EOF; }
238
239%%
240
241void lex_t::accept (int token, const char* sz)
242{
243 token_t t;
244 memset (&t, 0, sizeof (t));
245 t.copyString(sz);
246
247 /* tell lemon to parse the token */
248 parse (parser, token, t, this);
249}
250
251int lex_t::line ()const
252{
253 return yyget_lineno (scanner);
254}
255
256const char* lex_t::filename ()const
257{
258 return m_fileName;
259}
260
261void parse (MappedFile* mf)
262{
263 void* parser = bbparseAlloc (malloc);
264 yyscan_t scanner;
265 lex_t lex;
266
267 yylex_init (&scanner);
268
269 lex.parser = parser;
270 lex.scanner = scanner;
271 lex.mf = mf;
272 lex.rgbInput = mf->m_rgb;
273 lex.cbInput = mf->m_cb;
274 lex.parse = bbparse;
275 yyset_extra (&lex, scanner);
276
277
278 int result = yylex (scanner);
279
280 lex.accept (0);
281 bbparseTrace (NULL, NULL);
282
283 if (result != T_EOF)
284 WARNING ("premature end of file\n");
285
286 yylex_destroy (scanner);
287 bbparseFree (parser, free);
288}