diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2008-06-26 17:08:57 +1000 |
---|---|---|
committer | Jon Loeliger <jdl@jdl.com> | 2008-07-14 12:21:24 -0500 |
commit | 76e0622b687d795bb1379cf183c6ce8613e14658 (patch) | |
tree | 42112e0145be54ff721818426936c71a87616853 /dtc-lexer.l | |
parent | cdcb415851dc6c3e9550f27139c933fcaeb2d6a7 (diff) | |
download | dtc-76e0622b687d795bb1379cf183c6ce8613e14658.tar.gz |
dtc: Clean up lexing of include files
Currently we scan the /include/ directive as two tokens, the
"/include/" keyword itself, then the string giving the file name to
include. We use a special scanner state to keep the two linked
together, and use the scanner state stack to keep track of the
original state while we're parsing the two /include/ tokens.
This does mean that we need to enable the 'stack' option in flex,
which results in a not-easily-suppressed warning from the flex
boilerplate code. This is mildly irritating.
However, this two-token scanning of the /include/ directive also has
some extremely strange edge cases, because there are a variety of
tokens recognized in all scanner states, including INCLUDE. For
example the following strange dts file:
/include/ /dts-v1/;
/ {
/* ... */
};
Will be processed successfully with the /include/ being effectively
ignored: the '/dts-v1/' and ';' are recognized even in INCLUDE state,
then the ';' transitions us to PROPNODENAME state, throwing away
INCLUDE, and the previous state is never popped off the stack. Or
for another example this construct:
foo /include/ = "somefile.dts"
will be parsed as though it were:
foo = /include/ "somefile.dts"
Again, the '=' is scanned without leaving INCLUDE state, then the next
string triggers the include logic.
And finally, we use a different regexp for the string with the
included filename than the normal string regexpt, which is also
potentially weird.
This patch, therefore, cleans up the lexical handling of the /include/
directive. Instead of the INCLUDE state, we instead scan the whole
include directive, both keyword and filename as a single token. This
does mean a bit more complexity in extracting the filename out of
yytext, but I think it's worth it to avoid the strageness described
above. It also means it's no longer possible to put a comment between
the /include/ and the filename, but I'm really not very worried about
breaking files using such a strange construct.
Diffstat (limited to 'dtc-lexer.l')
-rw-r--r-- | dtc-lexer.l | 32 |
1 files changed, 13 insertions, 19 deletions
diff --git a/dtc-lexer.l b/dtc-lexer.l index 8f15c4d..44dbfd3 100644 --- a/dtc-lexer.l +++ b/dtc-lexer.l @@ -18,7 +18,7 @@ * USA */ -%option noyywrap nounput yylineno stack +%option noyywrap nounput yylineno %x INCLUDE %x BYTESTRING @@ -28,6 +28,10 @@ PROPNODECHAR [a-zA-Z0-9,._+*#?@-] PATHCHAR ({PROPNODECHAR}|[/]) LABEL [a-zA-Z_][a-zA-Z0-9_]* +STRING \"([^\\"]|\\.)*\" +WS [[:space:]] +COMMENT "/*"([^*]|\*+[^*/])*\*+"/" +LINECOMMENT "//".*\n %{ #include "dtc.h" @@ -58,22 +62,19 @@ static int pop_input_file(void); %} %% -<*>"/include/" yy_push_state(INCLUDE); - -<INCLUDE>\"[^"\n]*\" { - yytext[strlen(yytext) - 1] = 0; - push_input_file(yytext + 1); - yy_pop_state(); +<*>"/include/"{WS}*{STRING} { + char *name = strchr(yytext, '\"') + 1; + yytext[yyleng-1] = '\0'; + push_input_file(name); } - <*><<EOF>> { if (!pop_input_file()) { yyterminate(); } } -<*>\"([^\\"]|\\.)*\" { +<*>{STRING} { yylloc.file = srcpos_file; yylloc.first_line = yylineno; DPRINT("String: %s\n", yytext); @@ -197,16 +198,9 @@ static int pop_input_file(void); return DT_INCBIN; } -<*>[[:space:]]+ /* eat whitespace */ - -<*>"/*"([^*]|\*+[^*/])*\*+"/" { - yylloc.file = srcpos_file; - yylloc.first_line = yylineno; - DPRINT("Comment: %s\n", yytext); - /* eat comments */ - } - -<*>"//".*\n /* eat line comments */ +<*>{WS}+ /* eat whitespace */ +<*>{COMMENT}+ /* eat C-style comments */ +<*>{LINECOMMENT}+ /* eat C++-style comments */ <*>. { yylloc.file = srcpos_file; |