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 never-interactive 22 23 %x INCLUDE 24 %x BYTESTRING 25 %x PROPNODENAME 26 %s V1 27 28 PROPNODECHAR [a-zA-Z0-9,._+*#?@-] 29 PATHCHAR ({PROPNODECHAR}|[/]) 30 LABEL [a-zA-Z_][a-zA-Z0-9_]* 31 STRING \"([^\\"]|\\.)*\" 32 CHAR_LITERAL '([^']|\\')*' 33 WS [[:space:]] 34 COMMENT "/*"([^*]|\*+[^*/])*\*+"/" 35 LINECOMMENT "//".*\n 36 37 %{ 38 #include "dtc.h" 39 #include "srcpos.h" 40 #include "dtc-parser.tab.h" 41 42 YYLTYPE yylloc; 43 44 /* CAUTION: this will stop working if we ever use yyless() or yyunput() */ 45 #define YY_USER_ACTION \ 46 { \ 47 srcpos_update(&yylloc, yytext, yyleng); \ 48 } 49 50 /*#define LEXDEBUG 1*/ 51 52 #ifdef LEXDEBUG 53 #define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__) 54 #else 55 #define DPRINT(fmt, ...) do { } while (0) 56 #endif 57 58 static int dts_version = 1; 59 60 #define BEGIN_DEFAULT() DPRINT("<V1>\n"); \ 61 BEGIN(V1); \ 62 63 static void push_input_file(const char *filename); 64 static int pop_input_file(void); 65 %} 66 67 %% 68 <*>"/include/"{WS}*{STRING} { 69 char *name = strchr(yytext, '\"') + 1; 70 yytext[yyleng-1] = '\0'; 71 push_input_file(name); 72 } 73 74 <*>^"#"(line)?{WS}+[0-9]+{WS}+{STRING}({WS}+[0-9]+)? { 75 char *line, *tmp, *fn; 76 /* skip text before line # */ 77 line = yytext; 78 while (!isdigit(*line)) 79 line++; 80 /* skip digits in line # */ 81 tmp = line; 82 while (!isspace(*tmp)) 83 tmp++; 84 /* "NULL"-terminate line # */ 85 *tmp = '\0'; 86 /* start of filename */ 87 fn = strchr(tmp + 1, '"') + 1; 88 /* strip trailing " from filename */ 89 tmp = strchr(fn, '"'); 90 *tmp = 0; 91 /* -1 since #line is the number of the next line */ 92 srcpos_set_line(xstrdup(fn), atoi(line) - 1); 93 } 94 95 <*><<EOF>> { 96 if (!pop_input_file()) { 97 yyterminate(); 98 } 99 } 100 101 <*>{STRING} { 102 DPRINT("String: %s\n", yytext); 103 yylval.data = data_copy_escape_string(yytext+1, 104 yyleng-2); 105 return DT_STRING; 106 } 107 108 <*>"/dts-v1/" { 109 DPRINT("Keyword: /dts-v1/\n"); 110 dts_version = 1; 111 BEGIN_DEFAULT(); 112 return DT_V1; 113 } 114 115 <*>"/memreserve/" { 116 DPRINT("Keyword: /memreserve/\n"); 117 BEGIN_DEFAULT(); 118 return DT_MEMRESERVE; 119 } 120 121 <*>"/bits/" { 122 DPRINT("Keyword: /bits/\n"); 123 BEGIN_DEFAULT(); 124 return DT_BITS; 125 } 126 127 <*>"/delete-property/" { 128 DPRINT("Keyword: /delete-property/\n"); 129 DPRINT("<PROPNODENAME>\n"); 130 BEGIN(PROPNODENAME); 131 return DT_DEL_PROP; 132 } 133 134 <*>"/delete-node/" { 135 DPRINT("Keyword: /delete-node/\n"); 136 DPRINT("<PROPNODENAME>\n"); 137 BEGIN(PROPNODENAME); 138 return DT_DEL_NODE; 139 } 140 141 <*>{LABEL}: { 142 DPRINT("Label: %s\n", yytext); 143 yylval.labelref = xstrdup(yytext); 144 yylval.labelref[yyleng-1] = '\0'; 145 return DT_LABEL; 146 } 147 148 <V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? { 149 yylval.literal = xstrdup(yytext); 150 DPRINT("Literal: '%s'\n", yylval.literal); 151 return DT_LITERAL; 152 } 153 154 <*>{CHAR_LITERAL} { 155 yytext[yyleng-1] = '\0'; 156 yylval.literal = xstrdup(yytext+1); 157 DPRINT("Character literal: %s\n", yylval.literal); 158 return DT_CHAR_LITERAL; 159 } 160 161 <*>\&{LABEL} { /* label reference */ 162 DPRINT("Ref: %s\n", yytext+1); 163 yylval.labelref = xstrdup(yytext+1); 164 return DT_REF; 165 } 166 167 <*>"&{/"{PATHCHAR}+\} { /* new-style path reference */ 168 yytext[yyleng-1] = '\0'; 169 DPRINT("Ref: %s\n", yytext+2); 170 yylval.labelref = xstrdup(yytext+2); 171 return DT_REF; 172 } 173 174 <BYTESTRING>[0-9a-fA-F]{2} { 175 yylval.byte = strtol(yytext, NULL, 16); 176 DPRINT("Byte: %02x\n", (int)yylval.byte); 177 return DT_BYTE; 178 } 179 180 <BYTESTRING>"]" { 181 DPRINT("/BYTESTRING\n"); 182 BEGIN_DEFAULT(); 183 return ']'; 184 } 185 186 <PROPNODENAME>\\?{PROPNODECHAR}+ { 187 DPRINT("PropNodeName: %s\n", yytext); 188 yylval.propnodename = xstrdup((yytext[0] == '\\') ? 189 yytext + 1 : yytext); 190 BEGIN_DEFAULT(); 191 return DT_PROPNODENAME; 192 } 193 194 "/incbin/" { 195 DPRINT("Binary Include\n"); 196 return DT_INCBIN; 197 } 198 199 <*>{WS}+ /* eat whitespace */ 200 <*>{COMMENT}+ /* eat C-style comments */ 201 <*>{LINECOMMENT}+ /* eat C++-style comments */ 202 203 <*>"<<" { return DT_LSHIFT; }; 204 <*>">>" { return DT_RSHIFT; }; 205 <*>"<=" { return DT_LE; }; 206 <*>">=" { return DT_GE; }; 207 <*>"==" { return DT_EQ; }; 208 <*>"!=" { return DT_NE; }; 209 <*>"&&" { return DT_AND; }; 210 <*>"||" { return DT_OR; }; 211 212 <*>. { 213 DPRINT("Char: %c (\\x%02x)\n", yytext[0], 214 (unsigned)yytext[0]); 215 if (yytext[0] == '[') { 216 DPRINT("<BYTESTRING>\n"); 217 BEGIN(BYTESTRING); 218 } 219 if ((yytext[0] == '{') 220 || (yytext[0] == ';')) { 221 DPRINT("<PROPNODENAME>\n"); 222 BEGIN(PROPNODENAME); 223 } 224 return yytext[0]; 225 } 226 227 %% 228 229 static void push_input_file(const char *filename) 230 { 231 assert(filename); 232 233 srcfile_push(filename); 234 235 yyin = current_srcfile->f; 236 237 yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE)); 238 } 239 240 241 static int pop_input_file(void) 242 { 243 if (srcfile_pop() == 0) 244 return 0; 245 246 yypop_buffer_state(); 247 yyin = current_srcfile->f; 248 249 return 1; 250 } 251