summaryrefslogtreecommitdiff
path: root/dtc-lexer.l
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2008-06-26 17:08:57 +1000
committerJon Loeliger <jdl@jdl.com>2008-07-14 12:21:24 -0500
commit76e0622b687d795bb1379cf183c6ce8613e14658 (patch)
tree42112e0145be54ff721818426936c71a87616853 /dtc-lexer.l
parentcdcb415851dc6c3e9550f27139c933fcaeb2d6a7 (diff)
downloaddtc-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.l32
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;