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 %locations << 6 << 7 %{ 20 %{ 8 #include <stdio.h> 21 #include <stdio.h> 9 #include <inttypes.h> 22 #include <inttypes.h> 10 23 11 #include "dtc.h" 24 #include "dtc.h" 12 #include "srcpos.h" 25 #include "srcpos.h" 13 26 14 extern int yylex(void); 27 extern int yylex(void); 15 extern void yyerror(char const *s); 28 extern void yyerror(char const *s); 16 #define ERROR(loc, ...) \ 29 #define ERROR(loc, ...) \ 17 do { \ 30 do { \ 18 srcpos_error((loc), "Error", _ 31 srcpos_error((loc), "Error", __VA_ARGS__); \ 19 treesource_error = true; \ 32 treesource_error = true; \ 20 } while (0) 33 } while (0) 21 34 22 #define YYERROR_CALL(msg) yyerror(msg) << 23 << 24 extern struct dt_info *parser_output; 35 extern struct dt_info *parser_output; 25 extern bool treesource_error; 36 extern bool treesource_error; 26 << 27 static bool is_ref_relative(const char *ref) << 28 { << 29 return ref[0] != '/' && strchr(&ref[1] << 30 } << 31 << 32 %} 37 %} 33 38 34 %union { 39 %union { 35 char *propnodename; 40 char *propnodename; 36 char *labelref; 41 char *labelref; 37 uint8_t byte; 42 uint8_t byte; 38 struct data data; 43 struct data data; 39 44 40 struct { 45 struct { 41 struct data data; 46 struct data data; 42 int bits; 47 int bits; 43 } array; 48 } array; 44 49 45 struct property *prop; 50 struct property *prop; 46 struct property *proplist; 51 struct property *proplist; 47 struct node *node; 52 struct node *node; 48 struct node *nodelist; 53 struct node *nodelist; 49 struct reserve_info *re; 54 struct reserve_info *re; 50 uint64_t integer; 55 uint64_t integer; 51 unsigned int flags; 56 unsigned int flags; 52 } 57 } 53 58 54 %token DT_V1 59 %token DT_V1 55 %token DT_PLUGIN 60 %token DT_PLUGIN 56 %token DT_MEMRESERVE 61 %token DT_MEMRESERVE 57 %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ D 62 %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR 58 %token DT_BITS 63 %token DT_BITS 59 %token DT_DEL_PROP 64 %token DT_DEL_PROP 60 %token DT_DEL_NODE 65 %token DT_DEL_NODE 61 %token DT_OMIT_NO_REF 66 %token DT_OMIT_NO_REF 62 %token <propnodename> DT_PROPNODENAME 67 %token <propnodename> DT_PROPNODENAME 63 %token <integer> DT_LITERAL 68 %token <integer> DT_LITERAL 64 %token <integer> DT_CHAR_LITERAL 69 %token <integer> DT_CHAR_LITERAL 65 %token <byte> DT_BYTE 70 %token <byte> DT_BYTE 66 %token <data> DT_STRING 71 %token <data> DT_STRING 67 %token <labelref> DT_LABEL 72 %token <labelref> DT_LABEL 68 %token <labelref> DT_LABEL_REF !! 73 %token <labelref> DT_REF 69 %token <labelref> DT_PATH_REF << 70 %token DT_INCBIN 74 %token DT_INCBIN 71 75 72 %type <data> propdata 76 %type <data> propdata 73 %type <data> propdataprefix 77 %type <data> propdataprefix 74 %type <flags> header 78 %type <flags> header 75 %type <flags> headers 79 %type <flags> headers 76 %type <re> memreserve 80 %type <re> memreserve 77 %type <re> memreserves 81 %type <re> memreserves 78 %type <array> arrayprefix 82 %type <array> arrayprefix 79 %type <data> bytestring 83 %type <data> bytestring 80 %type <prop> propdef 84 %type <prop> propdef 81 %type <proplist> proplist 85 %type <proplist> proplist 82 %type <labelref> dt_ref << 83 86 84 %type <node> devicetree 87 %type <node> devicetree 85 %type <node> nodedef 88 %type <node> nodedef 86 %type <node> subnode 89 %type <node> subnode 87 %type <nodelist> subnodes 90 %type <nodelist> subnodes 88 91 89 %type <integer> integer_prim 92 %type <integer> integer_prim 90 %type <integer> integer_unary 93 %type <integer> integer_unary 91 %type <integer> integer_mul 94 %type <integer> integer_mul 92 %type <integer> integer_add 95 %type <integer> integer_add 93 %type <integer> integer_shift 96 %type <integer> integer_shift 94 %type <integer> integer_rela 97 %type <integer> integer_rela 95 %type <integer> integer_eq 98 %type <integer> integer_eq 96 %type <integer> integer_bitand 99 %type <integer> integer_bitand 97 %type <integer> integer_bitxor 100 %type <integer> integer_bitxor 98 %type <integer> integer_bitor 101 %type <integer> integer_bitor 99 %type <integer> integer_and 102 %type <integer> integer_and 100 %type <integer> integer_or 103 %type <integer> integer_or 101 %type <integer> integer_trinary 104 %type <integer> integer_trinary 102 %type <integer> integer_expr 105 %type <integer> integer_expr 103 106 104 %% 107 %% 105 108 106 sourcefile: 109 sourcefile: 107 headers memreserves devicetree 110 headers memreserves devicetree 108 { 111 { 109 parser_output = build_ 112 parser_output = build_dt_info($1, $2, $3, 110 113 guess_boot_cpuid($3)); 111 } 114 } 112 ; 115 ; 113 116 114 header: 117 header: 115 DT_V1 ';' 118 DT_V1 ';' 116 { 119 { 117 $$ = DTSF_V1; 120 $$ = DTSF_V1; 118 } 121 } 119 | DT_V1 ';' DT_PLUGIN ';' 122 | DT_V1 ';' DT_PLUGIN ';' 120 { 123 { 121 $$ = DTSF_V1 | DTSF_PL 124 $$ = DTSF_V1 | DTSF_PLUGIN; 122 } 125 } 123 ; 126 ; 124 127 125 headers: 128 headers: 126 header 129 header 127 | header headers 130 | header headers 128 { 131 { 129 if ($2 != $1) 132 if ($2 != $1) 130 ERROR(&@2, "He 133 ERROR(&@2, "Header flags don't match earlier ones"); 131 $$ = $1; 134 $$ = $1; 132 } 135 } 133 ; 136 ; 134 137 135 memreserves: 138 memreserves: 136 /* empty */ 139 /* empty */ 137 { 140 { 138 $$ = NULL; 141 $$ = NULL; 139 } 142 } 140 | memreserve memreserves 143 | memreserve memreserves 141 { 144 { 142 $$ = chain_reserve_ent 145 $$ = chain_reserve_entry($1, $2); 143 } 146 } 144 ; 147 ; 145 148 146 memreserve: 149 memreserve: 147 DT_MEMRESERVE integer_prim integer_p 150 DT_MEMRESERVE integer_prim integer_prim ';' 148 { 151 { 149 $$ = build_reserve_ent 152 $$ = build_reserve_entry($2, $3); 150 } 153 } 151 | DT_LABEL memreserve 154 | DT_LABEL memreserve 152 { 155 { 153 add_label(&$2->labels, 156 add_label(&$2->labels, $1); 154 $$ = $2; 157 $$ = $2; 155 } 158 } 156 ; 159 ; 157 160 158 dt_ref: DT_LABEL_REF | DT_PATH_REF; << 159 << 160 devicetree: 161 devicetree: 161 '/' nodedef 162 '/' nodedef 162 { 163 { 163 $$ = name_node($2, "") 164 $$ = name_node($2, ""); 164 } 165 } 165 | devicetree '/' nodedef 166 | devicetree '/' nodedef 166 { 167 { 167 $$ = merge_nodes($1, $ 168 $$ = merge_nodes($1, $3); 168 } 169 } 169 | dt_ref nodedef !! 170 | DT_REF nodedef 170 { 171 { 171 /* 172 /* 172 * We rely on the rule 173 * We rely on the rule being always: 173 * versioninfo plugi 174 * versioninfo plugindecl memreserves devicetree 174 * so $-1 is what we w 175 * so $-1 is what we want (plugindecl) 175 */ 176 */ 176 if (!($<flags>-1 & DTS 177 if (!($<flags>-1 & DTSF_PLUGIN)) 177 ERROR(&@2, "La 178 ERROR(&@2, "Label or path %s not found", $1); 178 else if (is_ref_relati !! 179 $$ = add_orphan_node(name_node(build_node(NULL, NULL), ""), $2, $1); 179 ERROR(&@2, "La << 180 $$ = add_orphan_node( << 181 name_n << 182 << 183 $2, $1 << 184 } 180 } 185 | devicetree DT_LABEL dt_ref nodedef !! 181 | devicetree DT_LABEL DT_REF nodedef 186 { 182 { 187 struct node *target = 183 struct node *target = get_node_by_ref($1, $3); 188 184 189 if (($<flags>-1 & DTSF << 190 ERROR(&@2, "La << 191 << 192 if (target) { 185 if (target) { 193 add_label(&tar 186 add_label(&target->labels, $2); 194 merge_nodes(ta 187 merge_nodes(target, $4); 195 } else 188 } else 196 ERROR(&@3, "La 189 ERROR(&@3, "Label or path %s not found", $3); 197 $$ = $1; 190 $$ = $1; 198 } 191 } 199 | devicetree DT_PATH_REF nodedef !! 192 | devicetree DT_REF nodedef 200 { 193 { 201 /* 194 /* 202 * We rely on the rule 195 * We rely on the rule being always: 203 * versioninfo plugi 196 * versioninfo plugindecl memreserves devicetree 204 * so $-1 is what we w 197 * so $-1 is what we want (plugindecl) 205 */ 198 */ 206 if ($<flags>-1 & DTSF_ 199 if ($<flags>-1 & DTSF_PLUGIN) { 207 if (is_ref_rel << 208 ERROR( << 209 add_orphan_nod 200 add_orphan_node($1, $3, $2); 210 } else { 201 } else { 211 struct node *t 202 struct node *target = get_node_by_ref($1, $2); 212 203 213 if (target) 204 if (target) 214 merge_ 205 merge_nodes(target, $3); 215 else 206 else 216 ERROR( 207 ERROR(&@2, "Label or path %s not found", $2); 217 } 208 } 218 $$ = $1; 209 $$ = $1; 219 } 210 } 220 | devicetree DT_LABEL_REF nodedef !! 211 | devicetree DT_DEL_NODE DT_REF ';' 221 { << 222 struct node *target = << 223 << 224 if (target) { << 225 merge_nodes(ta << 226 } else { << 227 /* << 228 * We rely on << 229 * versionin << 230 * so $-1 is w << 231 */ << 232 if ($<flags>-1 << 233 add_or << 234 else << 235 ERROR( << 236 } << 237 $$ = $1; << 238 } << 239 | devicetree DT_DEL_NODE dt_ref ';' << 240 { 212 { 241 struct node *target = 213 struct node *target = get_node_by_ref($1, $3); 242 214 243 if (target) 215 if (target) 244 delete_node(ta 216 delete_node(target); 245 else 217 else 246 ERROR(&@3, "La 218 ERROR(&@3, "Label or path %s not found", $3); 247 219 248 220 249 $$ = $1; 221 $$ = $1; 250 } 222 } 251 | devicetree DT_OMIT_NO_REF dt_ref ';' !! 223 | devicetree DT_OMIT_NO_REF DT_REF ';' 252 { 224 { 253 struct node *target = 225 struct node *target = get_node_by_ref($1, $3); 254 226 255 if (target) 227 if (target) 256 omit_node_if_u 228 omit_node_if_unused(target); 257 else 229 else 258 ERROR(&@3, "La 230 ERROR(&@3, "Label or path %s not found", $3); 259 231 260 232 261 $$ = $1; 233 $$ = $1; 262 } 234 } 263 ; 235 ; 264 236 265 nodedef: 237 nodedef: 266 '{' proplist subnodes '}' ';' 238 '{' proplist subnodes '}' ';' 267 { 239 { 268 $$ = build_node($2, $3 !! 240 $$ = build_node($2, $3); 269 } 241 } 270 ; 242 ; 271 243 272 proplist: 244 proplist: 273 /* empty */ 245 /* empty */ 274 { 246 { 275 $$ = NULL; 247 $$ = NULL; 276 } 248 } 277 | proplist propdef 249 | proplist propdef 278 { 250 { 279 $$ = chain_property($2 251 $$ = chain_property($2, $1); 280 } 252 } 281 ; 253 ; 282 254 283 propdef: 255 propdef: 284 DT_PROPNODENAME '=' propdata ';' 256 DT_PROPNODENAME '=' propdata ';' 285 { 257 { 286 $$ = build_property($1 !! 258 $$ = build_property($1, $3); 287 free($1); << 288 } 259 } 289 | DT_PROPNODENAME ';' 260 | DT_PROPNODENAME ';' 290 { 261 { 291 $$ = build_property($1 !! 262 $$ = build_property($1, empty_data); 292 free($1); << 293 } 263 } 294 | DT_DEL_PROP DT_PROPNODENAME ';' 264 | DT_DEL_PROP DT_PROPNODENAME ';' 295 { 265 { 296 $$ = build_property_de 266 $$ = build_property_delete($2); 297 free($2); << 298 } 267 } 299 | DT_LABEL propdef 268 | DT_LABEL propdef 300 { 269 { 301 add_label(&$2->labels, 270 add_label(&$2->labels, $1); 302 $$ = $2; 271 $$ = $2; 303 } 272 } 304 ; 273 ; 305 274 306 propdata: 275 propdata: 307 propdataprefix DT_STRING 276 propdataprefix DT_STRING 308 { 277 { 309 $$ = data_merge($1, $2 278 $$ = data_merge($1, $2); 310 } 279 } 311 | propdataprefix arrayprefix '>' 280 | propdataprefix arrayprefix '>' 312 { 281 { 313 $$ = data_merge($1, $2 282 $$ = data_merge($1, $2.data); 314 } 283 } 315 | propdataprefix '[' bytestring ']' 284 | propdataprefix '[' bytestring ']' 316 { 285 { 317 $$ = data_merge($1, $3 286 $$ = data_merge($1, $3); 318 } 287 } 319 | propdataprefix dt_ref !! 288 | propdataprefix DT_REF 320 { 289 { 321 $1 = data_add_marker($ << 322 $$ = data_add_marker($ 290 $$ = data_add_marker($1, REF_PATH, $2); 323 } 291 } 324 | propdataprefix DT_INCBIN '(' DT_STRI 292 | propdataprefix DT_INCBIN '(' DT_STRING ',' integer_prim ',' integer_prim ')' 325 { 293 { 326 FILE *f = srcfile_rela 294 FILE *f = srcfile_relative_open($4.val, NULL); 327 struct data d; 295 struct data d; 328 296 329 if ($6 != 0) 297 if ($6 != 0) 330 if (fseek(f, $ 298 if (fseek(f, $6, SEEK_SET) != 0) 331 die("C 299 die("Couldn't seek to offset %llu in \"%s\": %s", 332 (u 300 (unsigned long long)$6, $4.val, 333 st 301 strerror(errno)); 334 302 335 d = data_copy_file(f, 303 d = data_copy_file(f, $8); 336 304 337 $$ = data_merge($1, d) 305 $$ = data_merge($1, d); 338 fclose(f); 306 fclose(f); 339 } 307 } 340 | propdataprefix DT_INCBIN '(' DT_STRI 308 | propdataprefix DT_INCBIN '(' DT_STRING ')' 341 { 309 { 342 FILE *f = srcfile_rela 310 FILE *f = srcfile_relative_open($4.val, NULL); 343 struct data d = empty_ 311 struct data d = empty_data; 344 312 345 d = data_copy_file(f, 313 d = data_copy_file(f, -1); 346 314 347 $$ = data_merge($1, d) 315 $$ = data_merge($1, d); 348 fclose(f); 316 fclose(f); 349 } 317 } 350 | propdata DT_LABEL 318 | propdata DT_LABEL 351 { 319 { 352 $$ = data_add_marker($ 320 $$ = data_add_marker($1, LABEL, $2); 353 } 321 } 354 ; 322 ; 355 323 356 propdataprefix: 324 propdataprefix: 357 /* empty */ 325 /* empty */ 358 { 326 { 359 $$ = empty_data; 327 $$ = empty_data; 360 } 328 } 361 | propdata ',' 329 | propdata ',' 362 { 330 { 363 $$ = $1; 331 $$ = $1; 364 } 332 } 365 | propdataprefix DT_LABEL 333 | propdataprefix DT_LABEL 366 { 334 { 367 $$ = data_add_marker($ 335 $$ = data_add_marker($1, LABEL, $2); 368 } 336 } 369 ; 337 ; 370 338 371 arrayprefix: 339 arrayprefix: 372 DT_BITS DT_LITERAL '<' 340 DT_BITS DT_LITERAL '<' 373 { 341 { 374 unsigned long long bit 342 unsigned long long bits; 375 enum markertype type = << 376 343 377 bits = $2; 344 bits = $2; 378 345 379 switch (bits) { !! 346 if ((bits != 8) && (bits != 16) && 380 case 8: type = TYPE_UI !! 347 (bits != 32) && (bits != 64)) { 381 case 16: type = TYPE_U << 382 case 32: type = TYPE_U << 383 case 64: type = TYPE_U << 384 default: << 385 ERROR(&@2, "Ar 348 ERROR(&@2, "Array elements must be" 386 " 8, 16, 349 " 8, 16, 32 or 64-bits"); 387 bits = 32; 350 bits = 32; 388 } 351 } 389 352 390 $$.data = data_add_mar !! 353 $$.data = empty_data; 391 $$.bits = bits; 354 $$.bits = bits; 392 } 355 } 393 | '<' 356 | '<' 394 { 357 { 395 $$.data = data_add_mar !! 358 $$.data = empty_data; 396 $$.bits = 32; 359 $$.bits = 32; 397 } 360 } 398 | arrayprefix integer_prim 361 | arrayprefix integer_prim 399 { 362 { 400 if ($1.bits < 64) { 363 if ($1.bits < 64) { 401 uint64_t mask 364 uint64_t mask = (1ULL << $1.bits) - 1; 402 /* 365 /* 403 * Bits above 366 * Bits above mask must either be all zero 404 * (positive w 367 * (positive within range of mask) or all one 405 * (negative a 368 * (negative and sign-extended). The second 406 * condition i 369 * condition is true if when we set all bits 407 * within the 370 * within the mask to one (i.e. | in the 408 * mask), all 371 * mask), all bits are one. 409 */ 372 */ 410 if (($2 > mask !! 373 if (($2 > mask) && (($2 | mask) != -1ULL)) 411 char * !! 374 ERROR(&@2, "Value out of range for" 412 fprint !! 375 " %d-bit array element", $1.bits); 413 << 414 << 415 << 416 free(l << 417 } << 418 } 376 } 419 377 420 $$.data = data_append_ 378 $$.data = data_append_integer($1.data, $2, $1.bits); 421 } 379 } 422 | arrayprefix dt_ref !! 380 | arrayprefix DT_REF 423 { 381 { 424 uint64_t val = ~0ULL > 382 uint64_t val = ~0ULL >> (64 - $1.bits); 425 383 426 if ($1.bits == 32) 384 if ($1.bits == 32) 427 $1.data = data 385 $1.data = data_add_marker($1.data, 428 386 REF_PHANDLE, 429 387 $2); 430 else 388 else 431 ERROR(&@2, "Re 389 ERROR(&@2, "References are only allowed in " 432 "a 390 "arrays with 32-bit elements."); 433 391 434 $$.data = data_append_ 392 $$.data = data_append_integer($1.data, val, $1.bits); 435 } 393 } 436 | arrayprefix DT_LABEL 394 | arrayprefix DT_LABEL 437 { 395 { 438 $$.data = data_add_mar 396 $$.data = data_add_marker($1.data, LABEL, $2); 439 } 397 } 440 ; 398 ; 441 399 442 integer_prim: 400 integer_prim: 443 DT_LITERAL 401 DT_LITERAL 444 | DT_CHAR_LITERAL 402 | DT_CHAR_LITERAL 445 | '(' integer_expr ')' 403 | '(' integer_expr ')' 446 { 404 { 447 $$ = $2; 405 $$ = $2; 448 } 406 } 449 ; 407 ; 450 408 451 integer_expr: 409 integer_expr: 452 integer_trinary 410 integer_trinary 453 ; 411 ; 454 412 455 integer_trinary: 413 integer_trinary: 456 integer_or 414 integer_or 457 | integer_or '?' integer_expr ':' inte 415 | integer_or '?' integer_expr ':' integer_trinary { $$ = $1 ? $3 : $5; } 458 ; 416 ; 459 417 460 integer_or: 418 integer_or: 461 integer_and 419 integer_and 462 | integer_or DT_OR integer_and { $$ = 420 | integer_or DT_OR integer_and { $$ = $1 || $3; } 463 ; 421 ; 464 422 465 integer_and: 423 integer_and: 466 integer_bitor 424 integer_bitor 467 | integer_and DT_AND integer_bitor { $ 425 | integer_and DT_AND integer_bitor { $$ = $1 && $3; } 468 ; 426 ; 469 427 470 integer_bitor: 428 integer_bitor: 471 integer_bitxor 429 integer_bitxor 472 | integer_bitor '|' integer_bitxor { $ 430 | integer_bitor '|' integer_bitxor { $$ = $1 | $3; } 473 ; 431 ; 474 432 475 integer_bitxor: 433 integer_bitxor: 476 integer_bitand 434 integer_bitand 477 | integer_bitxor '^' integer_bitand { 435 | integer_bitxor '^' integer_bitand { $$ = $1 ^ $3; } 478 ; 436 ; 479 437 480 integer_bitand: 438 integer_bitand: 481 integer_eq 439 integer_eq 482 | integer_bitand '&' integer_eq { $$ = 440 | integer_bitand '&' integer_eq { $$ = $1 & $3; } 483 ; 441 ; 484 442 485 integer_eq: 443 integer_eq: 486 integer_rela 444 integer_rela 487 | integer_eq DT_EQ integer_rela { $$ = 445 | integer_eq DT_EQ integer_rela { $$ = $1 == $3; } 488 | integer_eq DT_NE integer_rela { $$ = 446 | integer_eq DT_NE integer_rela { $$ = $1 != $3; } 489 ; 447 ; 490 448 491 integer_rela: 449 integer_rela: 492 integer_shift 450 integer_shift 493 | integer_rela '<' integer_shift { $$ 451 | integer_rela '<' integer_shift { $$ = $1 < $3; } 494 | integer_rela '>' integer_shift { $$ 452 | integer_rela '>' integer_shift { $$ = $1 > $3; } 495 | integer_rela DT_LE integer_shift { $ 453 | integer_rela DT_LE integer_shift { $$ = $1 <= $3; } 496 | integer_rela DT_GE integer_shift { $ 454 | integer_rela DT_GE integer_shift { $$ = $1 >= $3; } 497 ; 455 ; 498 456 499 integer_shift: 457 integer_shift: 500 integer_shift DT_LSHIFT integer_add !! 458 integer_shift DT_LSHIFT integer_add { $$ = $1 << $3; } 501 | integer_shift DT_RSHIFT integer_add !! 459 | integer_shift DT_RSHIFT integer_add { $$ = $1 >> $3; } 502 | integer_add 460 | integer_add 503 ; 461 ; 504 462 505 integer_add: 463 integer_add: 506 integer_add '+' integer_mul { $$ = $ 464 integer_add '+' integer_mul { $$ = $1 + $3; } 507 | integer_add '-' integer_mul { $$ = $ 465 | integer_add '-' integer_mul { $$ = $1 - $3; } 508 | integer_mul 466 | integer_mul 509 ; 467 ; 510 468 511 integer_mul: 469 integer_mul: 512 integer_mul '*' integer_unary { $$ = 470 integer_mul '*' integer_unary { $$ = $1 * $3; } 513 | integer_mul '/' integer_unary 471 | integer_mul '/' integer_unary 514 { 472 { 515 if ($3 != 0) { 473 if ($3 != 0) { 516 $$ = $1 / $3; 474 $$ = $1 / $3; 517 } else { 475 } else { 518 ERROR(&@$, "Di 476 ERROR(&@$, "Division by zero"); 519 $$ = 0; 477 $$ = 0; 520 } 478 } 521 } 479 } 522 | integer_mul '%' integer_unary 480 | integer_mul '%' integer_unary 523 { 481 { 524 if ($3 != 0) { 482 if ($3 != 0) { 525 $$ = $1 % $3; 483 $$ = $1 % $3; 526 } else { 484 } else { 527 ERROR(&@$, "Di 485 ERROR(&@$, "Division by zero"); 528 $$ = 0; 486 $$ = 0; 529 } 487 } 530 } 488 } 531 | integer_unary 489 | integer_unary 532 ; 490 ; 533 491 534 integer_unary: 492 integer_unary: 535 integer_prim 493 integer_prim 536 | '-' integer_unary { $$ = -$2; } 494 | '-' integer_unary { $$ = -$2; } 537 | '~' integer_unary { $$ = ~$2; } 495 | '~' integer_unary { $$ = ~$2; } 538 | '!' integer_unary { $$ = !$2; } 496 | '!' integer_unary { $$ = !$2; } 539 ; 497 ; 540 498 541 bytestring: 499 bytestring: 542 /* empty */ 500 /* empty */ 543 { 501 { 544 $$ = data_add_marker(e !! 502 $$ = empty_data; 545 } 503 } 546 | bytestring DT_BYTE 504 | bytestring DT_BYTE 547 { 505 { 548 $$ = data_append_byte( 506 $$ = data_append_byte($1, $2); 549 } 507 } 550 | bytestring DT_LABEL 508 | bytestring DT_LABEL 551 { 509 { 552 $$ = data_add_marker($ 510 $$ = data_add_marker($1, LABEL, $2); 553 } 511 } 554 ; 512 ; 555 513 556 subnodes: 514 subnodes: 557 /* empty */ 515 /* empty */ 558 { 516 { 559 $$ = NULL; 517 $$ = NULL; 560 } 518 } 561 | subnode subnodes 519 | subnode subnodes 562 { 520 { 563 $$ = chain_node($1, $2 521 $$ = chain_node($1, $2); 564 } 522 } 565 | subnode propdef 523 | subnode propdef 566 { 524 { 567 ERROR(&@2, "Properties 525 ERROR(&@2, "Properties must precede subnodes"); 568 YYERROR; 526 YYERROR; 569 } 527 } 570 ; 528 ; 571 529 572 subnode: 530 subnode: 573 DT_PROPNODENAME nodedef 531 DT_PROPNODENAME nodedef 574 { 532 { 575 $$ = name_node($2, $1) 533 $$ = name_node($2, $1); 576 free($1); << 577 } 534 } 578 | DT_DEL_NODE DT_PROPNODENAME ';' 535 | DT_DEL_NODE DT_PROPNODENAME ';' 579 { 536 { 580 $$ = name_node(build_n !! 537 $$ = name_node(build_node_delete(), $2); 581 free($2); << 582 } 538 } 583 | DT_OMIT_NO_REF subnode 539 | DT_OMIT_NO_REF subnode 584 { 540 { 585 $$ = omit_node_if_unus 541 $$ = omit_node_if_unused($2); 586 } 542 } 587 | DT_LABEL subnode 543 | DT_LABEL subnode 588 { 544 { 589 add_label(&$2->labels, 545 add_label(&$2->labels, $1); 590 $$ = $2; 546 $$ = $2; 591 } 547 } 592 ; 548 ; 593 549 594 %% 550 %% 595 551 596 void yyerror(char const *s) 552 void yyerror(char const *s) 597 { 553 { 598 ERROR(&yylloc, "%s", s); 554 ERROR(&yylloc, "%s", s); 599 } 555 }
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.