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