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