dtc-lexer.l revision 204488
1/* 2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005. 3 * 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License as 7 * published by the Free Software Foundation; either version 2 of the 8 * License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 * USA 19 */ 20 21%option noyywrap nounput noinput yylineno 22 23%x INCLUDE 24%x BYTESTRING 25%x PROPNODENAME 26%s V1 27 28PROPNODECHAR [a-zA-Z0-9,._+*#?@-] 29PATHCHAR ({PROPNODECHAR}|[/]) 30LABEL [a-zA-Z_][a-zA-Z0-9_]* 31STRING \"([^\\"]|\\.)*\" 32WS [[:space:]] 33COMMENT "/*"([^*]|\*+[^*/])*\*+"/" 34LINECOMMENT "//".*\n 35 36%{ 37#include "dtc.h" 38#include "srcpos.h" 39#include "dtc-parser.tab.h" 40 41#define YY_USER_ACTION \ 42 { \ 43 yylloc.file = srcpos_file; \ 44 yylloc.first_line = yylineno; \ 45 } 46 47/*#define LEXDEBUG 1*/ 48 49#ifdef LEXDEBUG 50#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__) 51#else 52#define DPRINT(fmt, ...) do { } while (0) 53#endif 54 55static int dts_version = 1; 56 57#define BEGIN_DEFAULT() DPRINT("<V1>\n"); \ 58 BEGIN(V1); \ 59 60static void push_input_file(const char *filename); 61static int pop_input_file(void); 62%} 63 64%% 65<*>"/include/"{WS}*{STRING} { 66 char *name = strchr(yytext, '\"') + 1; 67 yytext[yyleng-1] = '\0'; 68 push_input_file(name); 69 } 70 71<*><<EOF>> { 72 if (!pop_input_file()) { 73 yyterminate(); 74 } 75 } 76 77<*>{STRING} { 78 DPRINT("String: %s\n", yytext); 79 yylval.data = data_copy_escape_string(yytext+1, 80 yyleng-2); 81 return DT_STRING; 82 } 83 84<*>"/dts-v1/" { 85 DPRINT("Keyword: /dts-v1/\n"); 86 dts_version = 1; 87 BEGIN_DEFAULT(); 88 return DT_V1; 89 } 90 91<*>"/memreserve/" { 92 DPRINT("Keyword: /memreserve/\n"); 93 BEGIN_DEFAULT(); 94 return DT_MEMRESERVE; 95 } 96 97<*>{LABEL}: { 98 DPRINT("Label: %s\n", yytext); 99 yylval.labelref = xstrdup(yytext); 100 yylval.labelref[yyleng-1] = '\0'; 101 return DT_LABEL; 102 } 103 104<V1>[0-9]+|0[xX][0-9a-fA-F]+ { 105 yylval.literal = xstrdup(yytext); 106 DPRINT("Literal: '%s'\n", yylval.literal); 107 return DT_LITERAL; 108 } 109 110\&{LABEL} { /* label reference */ 111 DPRINT("Ref: %s\n", yytext+1); 112 yylval.labelref = xstrdup(yytext+1); 113 return DT_REF; 114 } 115 116"&{/"{PATHCHAR}+\} { /* new-style path reference */ 117 yytext[yyleng-1] = '\0'; 118 DPRINT("Ref: %s\n", yytext+2); 119 yylval.labelref = xstrdup(yytext+2); 120 return DT_REF; 121 } 122 123<BYTESTRING>[0-9a-fA-F]{2} { 124 yylval.byte = strtol(yytext, NULL, 16); 125 DPRINT("Byte: %02x\n", (int)yylval.byte); 126 return DT_BYTE; 127 } 128 129<BYTESTRING>"]" { 130 DPRINT("/BYTESTRING\n"); 131 BEGIN_DEFAULT(); 132 return ']'; 133 } 134 135<PROPNODENAME>{PROPNODECHAR}+ { 136 DPRINT("PropNodeName: %s\n", yytext); 137 yylval.propnodename = xstrdup(yytext); 138 BEGIN_DEFAULT(); 139 return DT_PROPNODENAME; 140 } 141 142"/incbin/" { 143 DPRINT("Binary Include\n"); 144 return DT_INCBIN; 145 } 146 147<*>{WS}+ /* eat whitespace */ 148<*>{COMMENT}+ /* eat C-style comments */ 149<*>{LINECOMMENT}+ /* eat C++-style comments */ 150 151<*>. { 152 DPRINT("Char: %c (\\x%02x)\n", yytext[0], 153 (unsigned)yytext[0]); 154 if (yytext[0] == '[') { 155 DPRINT("<BYTESTRING>\n"); 156 BEGIN(BYTESTRING); 157 } 158 if ((yytext[0] == '{') 159 || (yytext[0] == ';')) { 160 DPRINT("<PROPNODENAME>\n"); 161 BEGIN(PROPNODENAME); 162 } 163 return yytext[0]; 164 } 165 166%% 167 168 169/* 170 * Stack of nested include file contexts. 171 */ 172 173struct incl_file { 174 struct dtc_file *file; 175 YY_BUFFER_STATE yy_prev_buf; 176 int yy_prev_lineno; 177 struct incl_file *prev; 178}; 179 180static struct incl_file *incl_file_stack; 181 182 183/* 184 * Detect infinite include recursion. 185 */ 186#define MAX_INCLUDE_DEPTH (100) 187 188static int incl_depth = 0; 189 190 191static void push_input_file(const char *filename) 192{ 193 struct incl_file *incl_file; 194 struct dtc_file *newfile; 195 struct search_path search, *searchptr = NULL; 196 197 assert(filename); 198 199 if (incl_depth++ >= MAX_INCLUDE_DEPTH) 200 die("Includes nested too deeply"); 201 202 if (srcpos_file) { 203 search.dir = srcpos_file->dir; 204 search.next = NULL; 205 search.prev = NULL; 206 searchptr = &search; 207 } 208 209 newfile = dtc_open_file(filename, searchptr); 210 211 incl_file = xmalloc(sizeof(struct incl_file)); 212 213 /* 214 * Save current context. 215 */ 216 incl_file->yy_prev_buf = YY_CURRENT_BUFFER; 217 incl_file->yy_prev_lineno = yylineno; 218 incl_file->file = srcpos_file; 219 incl_file->prev = incl_file_stack; 220 221 incl_file_stack = incl_file; 222 223 /* 224 * Establish new context. 225 */ 226 srcpos_file = newfile; 227 yylineno = 1; 228 yyin = newfile->file; 229 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); 230} 231 232 233static int pop_input_file(void) 234{ 235 struct incl_file *incl_file; 236 237 if (incl_file_stack == 0) 238 return 0; 239 240 dtc_close_file(srcpos_file); 241 242 /* 243 * Pop. 244 */ 245 --incl_depth; 246 incl_file = incl_file_stack; 247 incl_file_stack = incl_file->prev; 248 249 /* 250 * Recover old context. 251 */ 252 yy_delete_buffer(YY_CURRENT_BUFFER); 253 yy_switch_to_buffer(incl_file->yy_prev_buf); 254 yylineno = incl_file->yy_prev_lineno; 255 srcpos_file = incl_file->file; 256 yyin = incl_file->file ? incl_file->file->file : NULL; 257 258 /* 259 * Free old state. 260 */ 261 free(incl_file); 262 263 return 1; 264} 265