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.
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.
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
24 flex lexer specification for a BitBake input file parser.
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.
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.
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
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
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.
64 %option never-interactive
67 %option reentrant stack
74 #include "bitbakeparser.h"
77 extern void *bbparseAlloc(void *(*mallocProc)(size_t));
78 extern void bbparseFree(void *p, void (*freeProc)(void*));
79 extern void *bbparseAlloc(void *(*mallocProc)(size_t));
80 extern void *bbparse(void*, int, token_t, lex_t*);
81 extern void bbparseTrace(FILE *TraceFILE, char *zTracePrompt);
83 //static const char* rgbInput;
84 //static size_t cbInput;
94 errorUnsupportedFeature,
99 #define YY_EXTRA_TYPE lex_t*
101 /* Read from buffer */
102 #define YY_INPUT(buf,result,max_size) \
103 { yyextra->input(buf, &result, max_size); }
105 //#define YY_DECL static size_t yylex ()
108 do { lineError = yylineno; errorParse = e; yyterminate (); } while (0)
110 static const char* fixup_escapes (const char* sz);
128 K_ADDHANDLER "addhandler"
136 K_FAKEROOT "fakeroot"
138 K_EXPORT_FUNC "EXPORT_FUNCTIONS"
140 STRING \"([^\n\r]|"\\\n")*\"
141 SSTRING \'([^\n\r]|"\\\n")*\'
142 VALUE ([^'" \t\n])|([^'" \t\n]([^\n]|(\\\n))*[^'" \t\n])
145 C_SB [a-zA-Z0-9_+-./]
146 REF $\{{C_SS}{C_SB}*\}
148 VARIABLE $?{C_SS}({C_SB}*|{REF})*(\[[a-zA-Z0-9_]*\])?
149 FILENAME ([a-zA-Z_./]|{REF})(([-+a-zA-Z0-9_./]*)|{REF})*
166 {OP_APPEND} { BEGIN S_RVALUE;
167 yyextra->accept (T_OP_APPEND); }
168 {OP_PREPEND} { BEGIN S_RVALUE;
169 yyextra->accept (T_OP_PREPEND); }
170 {OP_IMMEDIATE} { BEGIN S_RVALUE;
171 yyextra->accept (T_OP_IMMEDIATE); }
172 {OP_ASSIGN} { BEGIN S_RVALUE;
173 yyextra->accept (T_OP_ASSIGN); }
174 {OP_PREDOT} { BEGIN S_RVALUE;
175 yyextra->accept (T_OP_PREDOT); }
176 {OP_POSTDOT} { BEGIN S_RVALUE;
177 yyextra->accept (T_OP_POSTDOT); }
178 {OP_COND} { BEGIN S_RVALUE;
179 yyextra->accept (T_OP_COND); }
181 <S_RVALUE>\\\n{C_SP}* { }
182 <S_RVALUE>{STRING} { BEGIN INITIAL;
184 while (cb && isspace (yytext[cb - 1]))
187 yyextra->accept (T_STRING, yytext + 1); }
188 <S_RVALUE>{SSTRING} { BEGIN INITIAL;
190 while (cb && isspace (yytext[cb - 1]))
193 yyextra->accept (T_STRING, yytext + 1); }
195 <S_RVALUE>{VALUE} { ERROR (errorUnexpectedInput); }
196 <S_RVALUE>{C_SP}*\n+ { BEGIN INITIAL;
197 yyextra->accept (T_STRING, NULL); }
199 {K_INCLUDE} { BEGIN S_INCLUDE;
200 yyextra->accept (T_INCLUDE); }
201 {K_REQUIRE} { BEGIN S_REQUIRE;
202 yyextra->accept (T_REQUIRE); }
203 {K_INHERIT} { BEGIN S_INHERIT;
204 yyextra->accept (T_INHERIT); }
205 {K_ADDTASK} { BEGIN S_TASK;
206 yyextra->accept (T_ADDTASK); }
207 {K_ADDHANDLER} { yyextra->accept (T_ADDHANDLER); }
208 {K_EXPORT_FUNC} { BEGIN S_FUNC;
209 yyextra->accept (T_EXPORT_FUNC); }
210 <S_TASK>{K_BEFORE} { yyextra->accept (T_BEFORE); }
211 <S_TASK>{K_AFTER} { yyextra->accept (T_AFTER); }
212 <INITIAL>{K_EXPORT} { yyextra->accept (T_EXPORT); }
214 <INITIAL>{K_FAKEROOT} { yyextra->accept (T_FAKEROOT); }
215 <INITIAL>{K_PYTHON} { yyextra->accept (T_PYTHON); }
216 {PROC}{C_SP}*{B_OPEN}{C_SP}*\n* { BEGIN S_PROC;
217 yyextra->accept (T_PROC_OPEN); }
218 <S_PROC>{B_CLOSE}{C_SP}*\n* { BEGIN INITIAL;
219 yyextra->accept (T_PROC_CLOSE); }
220 <S_PROC>([^}][^\n]*)?\n* { yyextra->accept (T_PROC_BODY, yytext); }
222 {K_DEF} { BEGIN S_DEF; }
223 <S_DEF>{SYMBOL} { BEGIN S_DEF_ARGS;
224 yyextra->accept (T_SYMBOL, yytext); }
225 <S_DEF_ARGS>[^\n:]*: { yyextra->accept (T_DEF_ARGS, yytext); }
226 <S_DEF_ARGS>{C_SP}*\n { BEGIN S_DEF_BODY; }
227 <S_DEF_BODY>{C_SP}+[^\n]*\n { yyextra->accept (T_DEF_BODY, yytext); }
228 <S_DEF_BODY>\n { yyextra->accept (T_DEF_BODY, yytext); }
229 <S_DEF_BODY>. { BEGIN INITIAL; unput (yytext[0]); }
233 <INITIAL>{SYMBOL} { yyextra->accept (T_SYMBOL, yytext); }
234 <INITIAL>{VARIABLE} { yyextra->accept (T_VARIABLE, yytext); }
236 <S_TASK>{SYMBOL} { yyextra->accept (T_TSYMBOL, yytext); }
237 <S_FUNC>{SYMBOL} { yyextra->accept (T_FSYMBOL, yytext); }
238 <S_INHERIT>{SYMBOL} { yyextra->accept (T_ISYMBOL, yytext); }
239 <S_INCLUDE>{FILENAME} { BEGIN INITIAL;
240 yyextra->accept (T_ISYMBOL, yytext); }
241 <S_REQUIRE>{FILENAME} { BEGIN INITIAL;
242 yyextra->accept (T_ISYMBOL, yytext); }
243 <S_TASK>\n { BEGIN INITIAL; }
244 <S_FUNC>\n { BEGIN INITIAL; }
245 <S_INHERIT>\n { BEGIN INITIAL; }
247 [ \t\r\n] /* Insignificant whitespace */
249 . { ERROR (errorUnexpectedInput); }
251 /* Check for premature termination */
252 <<EOF>> { return T_EOF; }
256 void lex_t::accept (int token, const char* sz)
259 memset (&t, 0, sizeof (t));
262 /* tell lemon to parse the token */
263 parse (parser, token, t, this);
266 void lex_t::input (char *buf, int *result, int max_size)
268 /* printf("lex_t::input %p %d\n", buf, max_size); */
269 *result = fread(buf, 1, max_size, file);
270 /* printf("lex_t::input result %d\n", *result); */
273 int lex_t::line ()const
275 /* printf("lex_t::line\n"); */
276 return yyget_lineno (scanner);
282 void parse (FILE* file, PyObject* data)
284 /* printf("parse bbparseAlloc\n"); */
285 void* parser = bbparseAlloc (malloc);
289 /* printf("parse yylex_init\n"); */
290 yylex_init (&scanner);
293 lex.scanner = scanner;
297 /*printf("parse yyset_extra\n"); */
298 yyset_extra (&lex, scanner);
300 /* printf("parse yylex\n"); */
301 int result = yylex (scanner);
303 /* printf("parse result %d\n", result); */
306 /* printf("parse lex.accept\n"); */
307 bbparseTrace (NULL, NULL);
308 /* printf("parse bbparseTrace\n"); */
311 printf ("premature end of file\n");
313 yylex_destroy (scanner);
314 bbparseFree (parser, free);