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