1 /* SPDX-License-Identifier: GPL-2.0-or-later * << 2 /* 1 /* 3 * (C) Copyright David Gibson <dwg@au1.ibm.com> 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 4 */ 19 */ 5 20 6 %option noyywrap nounput noinput never-interac 21 %option noyywrap nounput noinput never-interactive 7 22 8 %x BYTESTRING 23 %x BYTESTRING 9 %x PROPNODENAME 24 %x PROPNODENAME 10 %s V1 25 %s V1 11 26 12 PROPNODECHAR [a-zA-Z0-9,._+*#?@-] 27 PROPNODECHAR [a-zA-Z0-9,._+*#?@-] 13 PATHCHAR ({PROPNODECHAR}|[/]) 28 PATHCHAR ({PROPNODECHAR}|[/]) 14 LABEL [a-zA-Z_][a-zA-Z0-9_]* 29 LABEL [a-zA-Z_][a-zA-Z0-9_]* 15 STRING \"([^\\"]|\\.)*\" 30 STRING \"([^\\"]|\\.)*\" 16 CHAR_LITERAL '([^']|\\')*' 31 CHAR_LITERAL '([^']|\\')*' 17 WS [[:space:]] 32 WS [[:space:]] 18 COMMENT "/*"([^*]|\*+[^*/])*\*+"/" 33 COMMENT "/*"([^*]|\*+[^*/])*\*+"/" 19 LINECOMMENT "//".*\n 34 LINECOMMENT "//".*\n 20 35 21 %{ 36 %{ 22 #include "dtc.h" 37 #include "dtc.h" 23 #include "srcpos.h" 38 #include "srcpos.h" 24 #include "dtc-parser.tab.h" 39 #include "dtc-parser.tab.h" 25 40 26 extern bool treesource_error; 41 extern bool treesource_error; 27 42 28 /* CAUTION: this will stop working if we ever 43 /* CAUTION: this will stop working if we ever use yyless() or yyunput() */ 29 #define YY_USER_ACTION \ 44 #define YY_USER_ACTION \ 30 { \ 45 { \ 31 srcpos_update(&yylloc, yytext, 46 srcpos_update(&yylloc, yytext, yyleng); \ 32 } 47 } 33 48 34 /*#define LEXDEBUG 1*/ 49 /*#define LEXDEBUG 1*/ 35 50 36 #ifdef LEXDEBUG 51 #ifdef LEXDEBUG 37 #define DPRINT(fmt, ...) fprintf(stderr 52 #define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__) 38 #else 53 #else 39 #define DPRINT(fmt, ...) do { } while ( 54 #define DPRINT(fmt, ...) do { } while (0) 40 #endif 55 #endif 41 56 42 static int dts_version = 1; 57 static int dts_version = 1; 43 58 44 #define BEGIN_DEFAULT() DPRINT("<V1>\n 59 #define BEGIN_DEFAULT() DPRINT("<V1>\n"); \ 45 BEGIN(V1); \ 60 BEGIN(V1); \ 46 61 47 static void push_input_file(const char *filena 62 static void push_input_file(const char *filename); 48 static bool pop_input_file(void); 63 static bool pop_input_file(void); 49 static void PRINTF(1, 2) lexical_error(const c 64 static void PRINTF(1, 2) lexical_error(const char *fmt, ...); 50 65 51 %} 66 %} 52 67 53 %% 68 %% 54 <*>"/include/"{WS}*{STRING} { 69 <*>"/include/"{WS}*{STRING} { 55 char *name = strchr(yy 70 char *name = strchr(yytext, '\"') + 1; 56 yytext[yyleng-1] = '\0 71 yytext[yyleng-1] = '\0'; 57 push_input_file(name); 72 push_input_file(name); 58 } 73 } 59 74 60 <*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t] !! 75 <*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? { 61 char *line, *fnstart, 76 char *line, *fnstart, *fnend; 62 struct data fn; 77 struct data fn; 63 /* skip text before li 78 /* skip text before line # */ 64 line = yytext; 79 line = yytext; 65 while (!isdigit((unsig 80 while (!isdigit((unsigned char)*line)) 66 line++; 81 line++; 67 82 68 /* regexp ensures that 83 /* regexp ensures that first and list " 69 * in the whole yytext 84 * in the whole yytext are those at 70 * beginning and end o 85 * beginning and end of the filename string */ 71 fnstart = memchr(yytex 86 fnstart = memchr(yytext, '"', yyleng); 72 for (fnend = yytext + 87 for (fnend = yytext + yyleng - 1; 73 *fnend != '"'; fn 88 *fnend != '"'; fnend--) 74 ; 89 ; 75 assert(fnstart && fnen 90 assert(fnstart && fnend && (fnend > fnstart)); 76 91 77 fn = data_copy_escape_ 92 fn = data_copy_escape_string(fnstart + 1, 78 93 fnend - fnstart - 1); 79 94 80 /* Don't allow nuls in 95 /* Don't allow nuls in filenames */ 81 if (memchr(fn.val, '\0 96 if (memchr(fn.val, '\0', fn.len - 1)) 82 lexical_error( 97 lexical_error("nul in line number directive"); 83 98 84 /* -1 since #line is t 99 /* -1 since #line is the number of the next line */ 85 srcpos_set_line(xstrdu 100 srcpos_set_line(xstrdup(fn.val), atoi(line) - 1); 86 data_free(fn); 101 data_free(fn); 87 } 102 } 88 103 89 <*><<EOF>> { 104 <*><<EOF>> { 90 if (!pop_input_file()) 105 if (!pop_input_file()) { 91 yyterminate(); 106 yyterminate(); 92 } 107 } 93 } 108 } 94 109 95 <*>{STRING} { 110 <*>{STRING} { 96 DPRINT("String: %s\n", 111 DPRINT("String: %s\n", yytext); 97 yylval.data = data_cop 112 yylval.data = data_copy_escape_string(yytext+1, 98 yyleng 113 yyleng-2); 99 return DT_STRING; 114 return DT_STRING; 100 } 115 } 101 116 102 <*>"/dts-v1/" { 117 <*>"/dts-v1/" { 103 DPRINT("Keyword: /dts- 118 DPRINT("Keyword: /dts-v1/\n"); 104 dts_version = 1; 119 dts_version = 1; 105 BEGIN_DEFAULT(); 120 BEGIN_DEFAULT(); 106 return DT_V1; 121 return DT_V1; 107 } 122 } 108 123 109 <*>"/plugin/" { 124 <*>"/plugin/" { 110 DPRINT("Keyword: /plug 125 DPRINT("Keyword: /plugin/\n"); 111 return DT_PLUGIN; 126 return DT_PLUGIN; 112 } 127 } 113 128 114 <*>"/memreserve/" { 129 <*>"/memreserve/" { 115 DPRINT("Keyword: /memr 130 DPRINT("Keyword: /memreserve/\n"); 116 BEGIN_DEFAULT(); 131 BEGIN_DEFAULT(); 117 return DT_MEMRESERVE; 132 return DT_MEMRESERVE; 118 } 133 } 119 134 120 <*>"/bits/" { 135 <*>"/bits/" { 121 DPRINT("Keyword: /bits 136 DPRINT("Keyword: /bits/\n"); 122 BEGIN_DEFAULT(); 137 BEGIN_DEFAULT(); 123 return DT_BITS; 138 return DT_BITS; 124 } 139 } 125 140 126 <*>"/delete-property/" { 141 <*>"/delete-property/" { 127 DPRINT("Keyword: /dele 142 DPRINT("Keyword: /delete-property/\n"); 128 DPRINT("<PROPNODENAME> 143 DPRINT("<PROPNODENAME>\n"); 129 BEGIN(PROPNODENAME); 144 BEGIN(PROPNODENAME); 130 return DT_DEL_PROP; 145 return DT_DEL_PROP; 131 } 146 } 132 147 133 <*>"/delete-node/" { 148 <*>"/delete-node/" { 134 DPRINT("Keyword: /dele 149 DPRINT("Keyword: /delete-node/\n"); 135 DPRINT("<PROPNODENAME> 150 DPRINT("<PROPNODENAME>\n"); 136 BEGIN(PROPNODENAME); 151 BEGIN(PROPNODENAME); 137 return DT_DEL_NODE; 152 return DT_DEL_NODE; 138 } 153 } 139 154 140 <*>"/omit-if-no-ref/" { << 141 DPRINT("Keyword: /omit << 142 DPRINT("<PROPNODENAME> << 143 BEGIN(PROPNODENAME); << 144 return DT_OMIT_NO_REF; << 145 } << 146 << 147 <*>{LABEL}: { 155 <*>{LABEL}: { 148 DPRINT("Label: %s\n", 156 DPRINT("Label: %s\n", yytext); 149 yylval.labelref = xstr 157 yylval.labelref = xstrdup(yytext); 150 yylval.labelref[yyleng 158 yylval.labelref[yyleng-1] = '\0'; 151 return DT_LABEL; 159 return DT_LABEL; 152 } 160 } 153 161 154 <V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? 162 <V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? { 155 char *e; 163 char *e; 156 DPRINT("Integer Litera 164 DPRINT("Integer Literal: '%s'\n", yytext); 157 165 158 errno = 0; 166 errno = 0; 159 yylval.integer = strto 167 yylval.integer = strtoull(yytext, &e, 0); 160 168 161 if (*e && e[strspn(e, 169 if (*e && e[strspn(e, "UL")]) { 162 lexical_error( 170 lexical_error("Bad integer literal '%s'", 163 171 yytext); 164 } 172 } 165 173 166 if (errno == ERANGE) 174 if (errno == ERANGE) 167 lexical_error( 175 lexical_error("Integer literal '%s' out of range", 168 176 yytext); 169 else 177 else 170 /* ERANGE is t 178 /* ERANGE is the only strtoull error triggerable 171 * by strings 179 * by strings matching the pattern */ 172 assert(errno = 180 assert(errno == 0); 173 return DT_LITERAL; 181 return DT_LITERAL; 174 } 182 } 175 183 176 <*>{CHAR_LITERAL} { 184 <*>{CHAR_LITERAL} { 177 struct data d; 185 struct data d; 178 DPRINT("Character lite 186 DPRINT("Character literal: %s\n", yytext); 179 187 180 d = data_copy_escape_s 188 d = data_copy_escape_string(yytext+1, yyleng-2); 181 if (d.len == 1) { 189 if (d.len == 1) { 182 lexical_error( 190 lexical_error("Empty character literal"); 183 yylval.integer 191 yylval.integer = 0; 184 } else { 192 } else { 185 yylval.integer 193 yylval.integer = (unsigned char)d.val[0]; 186 194 187 if (d.len > 2) 195 if (d.len > 2) 188 lexica 196 lexical_error("Character literal has %d" 189 197 " characters instead of 1", 190 198 d.len - 1); 191 } 199 } 192 200 193 data_free(d); 201 data_free(d); 194 return DT_CHAR_LITERAL 202 return DT_CHAR_LITERAL; 195 } 203 } 196 204 197 <*>\&{LABEL} { /* label reference */ 205 <*>\&{LABEL} { /* label reference */ 198 DPRINT("Ref: %s\n", yy 206 DPRINT("Ref: %s\n", yytext+1); 199 yylval.labelref = xstr 207 yylval.labelref = xstrdup(yytext+1); 200 return DT_LABEL_REF; !! 208 return DT_REF; 201 } 209 } 202 210 203 <*>"&{"{PATHCHAR}*\} { /* new-style p !! 211 <*>"&{/"{PATHCHAR}*\} { /* new-style path reference */ 204 yytext[yyleng-1] = '\0 212 yytext[yyleng-1] = '\0'; 205 DPRINT("Ref: %s\n", yy 213 DPRINT("Ref: %s\n", yytext+2); 206 yylval.labelref = xstr 214 yylval.labelref = xstrdup(yytext+2); 207 return DT_PATH_REF; !! 215 return DT_REF; 208 } 216 } 209 217 210 <BYTESTRING>[0-9a-fA-F]{2} { 218 <BYTESTRING>[0-9a-fA-F]{2} { 211 yylval.byte = strtol(y 219 yylval.byte = strtol(yytext, NULL, 16); 212 DPRINT("Byte: %02x\n", 220 DPRINT("Byte: %02x\n", (int)yylval.byte); 213 return DT_BYTE; 221 return DT_BYTE; 214 } 222 } 215 223 216 <BYTESTRING>"]" { 224 <BYTESTRING>"]" { 217 DPRINT("/BYTESTRING\n" 225 DPRINT("/BYTESTRING\n"); 218 BEGIN_DEFAULT(); 226 BEGIN_DEFAULT(); 219 return ']'; 227 return ']'; 220 } 228 } 221 229 222 <PROPNODENAME>\\?{PROPNODECHAR}+ { 230 <PROPNODENAME>\\?{PROPNODECHAR}+ { 223 DPRINT("PropNodeName: 231 DPRINT("PropNodeName: %s\n", yytext); 224 yylval.propnodename = 232 yylval.propnodename = xstrdup((yytext[0] == '\\') ? 225 233 yytext + 1 : yytext); 226 BEGIN_DEFAULT(); 234 BEGIN_DEFAULT(); 227 return DT_PROPNODENAME 235 return DT_PROPNODENAME; 228 } 236 } 229 237 230 "/incbin/" { 238 "/incbin/" { 231 DPRINT("Binary Include 239 DPRINT("Binary Include\n"); 232 return DT_INCBIN; 240 return DT_INCBIN; 233 } 241 } 234 242 235 <*>{WS}+ /* eat whitespace */ 243 <*>{WS}+ /* eat whitespace */ 236 <*>{COMMENT}+ /* eat C-style comments */ 244 <*>{COMMENT}+ /* eat C-style comments */ 237 <*>{LINECOMMENT}+ /* eat C++-style comments */ 245 <*>{LINECOMMENT}+ /* eat C++-style comments */ 238 246 239 <*>"<<" { return DT_LSHIFT; }; 247 <*>"<<" { return DT_LSHIFT; }; 240 <*>">>" { return DT_RSHIFT; }; 248 <*>">>" { return DT_RSHIFT; }; 241 <*>"<=" { return DT_LE; }; 249 <*>"<=" { return DT_LE; }; 242 <*>">=" { return DT_GE; }; 250 <*>">=" { return DT_GE; }; 243 <*>"==" { return DT_EQ; }; 251 <*>"==" { return DT_EQ; }; 244 <*>"!=" { return DT_NE; }; 252 <*>"!=" { return DT_NE; }; 245 <*>"&&" { return DT_AND; }; 253 <*>"&&" { return DT_AND; }; 246 <*>"||" { return DT_OR; }; 254 <*>"||" { return DT_OR; }; 247 255 248 <*>. { 256 <*>. { 249 DPRINT("Char: %c (\\x% 257 DPRINT("Char: %c (\\x%02x)\n", yytext[0], 250 (unsigned)yyte 258 (unsigned)yytext[0]); 251 if (yytext[0] == '[') 259 if (yytext[0] == '[') { 252 DPRINT("<BYTES 260 DPRINT("<BYTESTRING>\n"); 253 BEGIN(BYTESTRI 261 BEGIN(BYTESTRING); 254 } 262 } 255 if ((yytext[0] == '{') 263 if ((yytext[0] == '{') 256 || (yytext[0] == ' 264 || (yytext[0] == ';')) { 257 DPRINT("<PROPN 265 DPRINT("<PROPNODENAME>\n"); 258 BEGIN(PROPNODE 266 BEGIN(PROPNODENAME); 259 } 267 } 260 return yytext[0]; 268 return yytext[0]; 261 } 269 } 262 270 263 %% 271 %% 264 272 265 static void push_input_file(const char *filena 273 static void push_input_file(const char *filename) 266 { 274 { 267 assert(filename); 275 assert(filename); 268 276 269 srcfile_push(filename); 277 srcfile_push(filename); 270 278 271 yyin = current_srcfile->f; 279 yyin = current_srcfile->f; 272 280 273 yypush_buffer_state(yy_create_buffer(y 281 yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE)); 274 } 282 } 275 283 276 284 277 static bool pop_input_file(void) 285 static bool pop_input_file(void) 278 { 286 { 279 if (srcfile_pop() == 0) 287 if (srcfile_pop() == 0) 280 return false; 288 return false; 281 289 282 yypop_buffer_state(); 290 yypop_buffer_state(); 283 yyin = current_srcfile->f; 291 yyin = current_srcfile->f; 284 292 285 return true; 293 return true; 286 } 294 } 287 295 288 static void lexical_error(const char *fmt, ... 296 static void lexical_error(const char *fmt, ...) 289 { 297 { 290 va_list ap; 298 va_list ap; 291 299 292 va_start(ap, fmt); 300 va_start(ap, fmt); 293 srcpos_verror(&yylloc, "Lexical error" 301 srcpos_verror(&yylloc, "Lexical error", fmt, ap); 294 va_end(ap); 302 va_end(ap); 295 303 296 treesource_error = true; 304 treesource_error = true; 297 } 305 }
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.