dtc-lexer.l revision 204489
1204431Sraj/* 2204431Sraj * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005. 3204431Sraj * 4204431Sraj * 5204431Sraj * This program is free software; you can redistribute it and/or 6204431Sraj * modify it under the terms of the GNU General Public License as 7204431Sraj * published by the Free Software Foundation; either version 2 of the 8204431Sraj * License, or (at your option) any later version. 9204431Sraj * 10204431Sraj * This program is distributed in the hope that it will be useful, 11204431Sraj * but WITHOUT ANY WARRANTY; without even the implied warranty of 12204431Sraj * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13204431Sraj * General Public License for more details. 14204431Sraj * 15204431Sraj * You should have received a copy of the GNU General Public License 16204431Sraj * along with this program; if not, write to the Free Software 17204431Sraj * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18204431Sraj * USA 19204431Sraj */ 20204431Sraj 21204433Sraj%option noyywrap nounput noinput yylineno 22204431Sraj 23204431Sraj%x INCLUDE 24204431Sraj%x BYTESTRING 25204431Sraj%x PROPNODENAME 26204431Sraj%s V1 27204431Sraj 28204431SrajPROPNODECHAR [a-zA-Z0-9,._+*#?@-] 29204431SrajPATHCHAR ({PROPNODECHAR}|[/]) 30204431SrajLABEL [a-zA-Z_][a-zA-Z0-9_]* 31204431SrajSTRING \"([^\\"]|\\.)*\" 32204431SrajWS [[:space:]] 33204431SrajCOMMENT "/*"([^*]|\*+[^*/])*\*+"/" 34204431SrajLINECOMMENT "//".*\n 35204431Sraj 36204431Sraj%{ 37204431Sraj#include "dtc.h" 38204431Sraj#include "srcpos.h" 39204431Sraj#include "dtc-parser.tab.h" 40204431Sraj 41204489SrajYYLTYPE yylloc; 42204489Sraj 43204433Sraj#define YY_USER_ACTION \ 44204433Sraj { \ 45204433Sraj yylloc.file = srcpos_file; \ 46204433Sraj yylloc.first_line = yylineno; \ 47204433Sraj } 48204431Sraj 49204431Sraj/*#define LEXDEBUG 1*/ 50204431Sraj 51204431Sraj#ifdef LEXDEBUG 52204431Sraj#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__) 53204431Sraj#else 54204431Sraj#define DPRINT(fmt, ...) do { } while (0) 55204431Sraj#endif 56204431Sraj 57204433Srajstatic int dts_version = 1; 58204431Sraj 59204433Sraj#define BEGIN_DEFAULT() DPRINT("<V1>\n"); \ 60204431Sraj BEGIN(V1); \ 61204431Sraj 62204431Srajstatic void push_input_file(const char *filename); 63204431Srajstatic int pop_input_file(void); 64204431Sraj%} 65204431Sraj 66204431Sraj%% 67204431Sraj<*>"/include/"{WS}*{STRING} { 68204431Sraj char *name = strchr(yytext, '\"') + 1; 69204431Sraj yytext[yyleng-1] = '\0'; 70204431Sraj push_input_file(name); 71204431Sraj } 72204431Sraj 73204431Sraj<*><<EOF>> { 74204431Sraj if (!pop_input_file()) { 75204431Sraj yyterminate(); 76204431Sraj } 77204431Sraj } 78204431Sraj 79204431Sraj<*>{STRING} { 80204431Sraj DPRINT("String: %s\n", yytext); 81204431Sraj yylval.data = data_copy_escape_string(yytext+1, 82204431Sraj yyleng-2); 83204431Sraj return DT_STRING; 84204431Sraj } 85204431Sraj 86204431Sraj<*>"/dts-v1/" { 87204431Sraj DPRINT("Keyword: /dts-v1/\n"); 88204431Sraj dts_version = 1; 89204431Sraj BEGIN_DEFAULT(); 90204431Sraj return DT_V1; 91204431Sraj } 92204431Sraj 93204431Sraj<*>"/memreserve/" { 94204431Sraj DPRINT("Keyword: /memreserve/\n"); 95204431Sraj BEGIN_DEFAULT(); 96204431Sraj return DT_MEMRESERVE; 97204431Sraj } 98204431Sraj 99204431Sraj<*>{LABEL}: { 100204431Sraj DPRINT("Label: %s\n", yytext); 101204433Sraj yylval.labelref = xstrdup(yytext); 102204431Sraj yylval.labelref[yyleng-1] = '\0'; 103204431Sraj return DT_LABEL; 104204431Sraj } 105204431Sraj 106204431Sraj<V1>[0-9]+|0[xX][0-9a-fA-F]+ { 107204433Sraj yylval.literal = xstrdup(yytext); 108204431Sraj DPRINT("Literal: '%s'\n", yylval.literal); 109204431Sraj return DT_LITERAL; 110204431Sraj } 111204431Sraj 112204431Sraj\&{LABEL} { /* label reference */ 113204431Sraj DPRINT("Ref: %s\n", yytext+1); 114204433Sraj yylval.labelref = xstrdup(yytext+1); 115204431Sraj return DT_REF; 116204431Sraj } 117204431Sraj 118204431Sraj"&{/"{PATHCHAR}+\} { /* new-style path reference */ 119204431Sraj yytext[yyleng-1] = '\0'; 120204431Sraj DPRINT("Ref: %s\n", yytext+2); 121204433Sraj yylval.labelref = xstrdup(yytext+2); 122204431Sraj return DT_REF; 123204431Sraj } 124204431Sraj 125204431Sraj<BYTESTRING>[0-9a-fA-F]{2} { 126204431Sraj yylval.byte = strtol(yytext, NULL, 16); 127204431Sraj DPRINT("Byte: %02x\n", (int)yylval.byte); 128204431Sraj return DT_BYTE; 129204431Sraj } 130204431Sraj 131204431Sraj<BYTESTRING>"]" { 132204431Sraj DPRINT("/BYTESTRING\n"); 133204431Sraj BEGIN_DEFAULT(); 134204431Sraj return ']'; 135204431Sraj } 136204431Sraj 137204431Sraj<PROPNODENAME>{PROPNODECHAR}+ { 138204431Sraj DPRINT("PropNodeName: %s\n", yytext); 139204433Sraj yylval.propnodename = xstrdup(yytext); 140204431Sraj BEGIN_DEFAULT(); 141204431Sraj return DT_PROPNODENAME; 142204431Sraj } 143204431Sraj 144204431Sraj"/incbin/" { 145204431Sraj DPRINT("Binary Include\n"); 146204431Sraj return DT_INCBIN; 147204431Sraj } 148204431Sraj 149204431Sraj<*>{WS}+ /* eat whitespace */ 150204431Sraj<*>{COMMENT}+ /* eat C-style comments */ 151204431Sraj<*>{LINECOMMENT}+ /* eat C++-style comments */ 152204431Sraj 153204431Sraj<*>. { 154204431Sraj DPRINT("Char: %c (\\x%02x)\n", yytext[0], 155204431Sraj (unsigned)yytext[0]); 156204431Sraj if (yytext[0] == '[') { 157204431Sraj DPRINT("<BYTESTRING>\n"); 158204431Sraj BEGIN(BYTESTRING); 159204431Sraj } 160204431Sraj if ((yytext[0] == '{') 161204431Sraj || (yytext[0] == ';')) { 162204431Sraj DPRINT("<PROPNODENAME>\n"); 163204431Sraj BEGIN(PROPNODENAME); 164204431Sraj } 165204431Sraj return yytext[0]; 166204431Sraj } 167204431Sraj 168204431Sraj%% 169204431Sraj 170204431Sraj 171204431Sraj/* 172204431Sraj * Stack of nested include file contexts. 173204431Sraj */ 174204431Sraj 175204431Srajstruct incl_file { 176204431Sraj struct dtc_file *file; 177204431Sraj YY_BUFFER_STATE yy_prev_buf; 178204431Sraj int yy_prev_lineno; 179204431Sraj struct incl_file *prev; 180204431Sraj}; 181204431Sraj 182204431Srajstatic struct incl_file *incl_file_stack; 183204431Sraj 184204431Sraj 185204431Sraj/* 186204431Sraj * Detect infinite include recursion. 187204431Sraj */ 188204431Sraj#define MAX_INCLUDE_DEPTH (100) 189204431Sraj 190204431Srajstatic int incl_depth = 0; 191204431Sraj 192204431Sraj 193204431Srajstatic void push_input_file(const char *filename) 194204431Sraj{ 195204431Sraj struct incl_file *incl_file; 196204431Sraj struct dtc_file *newfile; 197204431Sraj struct search_path search, *searchptr = NULL; 198204431Sraj 199204431Sraj assert(filename); 200204431Sraj 201204431Sraj if (incl_depth++ >= MAX_INCLUDE_DEPTH) 202204431Sraj die("Includes nested too deeply"); 203204431Sraj 204204431Sraj if (srcpos_file) { 205204431Sraj search.dir = srcpos_file->dir; 206204431Sraj search.next = NULL; 207204431Sraj search.prev = NULL; 208204431Sraj searchptr = &search; 209204431Sraj } 210204431Sraj 211204431Sraj newfile = dtc_open_file(filename, searchptr); 212204431Sraj 213204431Sraj incl_file = xmalloc(sizeof(struct incl_file)); 214204431Sraj 215204431Sraj /* 216204431Sraj * Save current context. 217204431Sraj */ 218204431Sraj incl_file->yy_prev_buf = YY_CURRENT_BUFFER; 219204431Sraj incl_file->yy_prev_lineno = yylineno; 220204431Sraj incl_file->file = srcpos_file; 221204431Sraj incl_file->prev = incl_file_stack; 222204431Sraj 223204431Sraj incl_file_stack = incl_file; 224204431Sraj 225204431Sraj /* 226204431Sraj * Establish new context. 227204431Sraj */ 228204431Sraj srcpos_file = newfile; 229204431Sraj yylineno = 1; 230204431Sraj yyin = newfile->file; 231204431Sraj yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); 232204431Sraj} 233204431Sraj 234204431Sraj 235204431Srajstatic int pop_input_file(void) 236204431Sraj{ 237204431Sraj struct incl_file *incl_file; 238204431Sraj 239204431Sraj if (incl_file_stack == 0) 240204431Sraj return 0; 241204431Sraj 242204431Sraj dtc_close_file(srcpos_file); 243204431Sraj 244204431Sraj /* 245204431Sraj * Pop. 246204431Sraj */ 247204431Sraj --incl_depth; 248204431Sraj incl_file = incl_file_stack; 249204431Sraj incl_file_stack = incl_file->prev; 250204431Sraj 251204431Sraj /* 252204431Sraj * Recover old context. 253204431Sraj */ 254204431Sraj yy_delete_buffer(YY_CURRENT_BUFFER); 255204431Sraj yy_switch_to_buffer(incl_file->yy_prev_buf); 256204431Sraj yylineno = incl_file->yy_prev_lineno; 257204431Sraj srcpos_file = incl_file->file; 258204431Sraj yyin = incl_file->file ? incl_file->file->file : NULL; 259204431Sraj 260204431Sraj /* 261204431Sraj * Free old state. 262204431Sraj */ 263204431Sraj free(incl_file); 264204431Sraj 265204431Sraj return 1; 266204431Sraj} 267