blob: a0316a3cc3099e206709fbaeddf50ca78aae5241 [file] [log] [blame]
Rob Herring12869ec2019-06-21 08:18:32 -06001// SPDX-License-Identifier: GPL-2.0-or-later
David Gibsona4da2e32007-12-18 15:06:42 +11002/*
3 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
David Gibsona4da2e32007-12-18 15:06:42 +11004 */
Rob Herring0cec1142019-12-26 15:36:47 -07005%locations
6
David Gibsona4da2e32007-12-18 15:06:42 +11007%{
David Gibsoned95d742008-08-07 12:24:17 +10008#include <stdio.h>
Rob Herring6f05afc2017-01-04 10:45:20 -06009#include <inttypes.h>
David Gibsoned95d742008-08-07 12:24:17 +100010
David Gibsona4da2e32007-12-18 15:06:42 +110011#include "dtc.h"
12#include "srcpos.h"
13
David Gibsoned95d742008-08-07 12:24:17 +100014extern int yylex(void);
John Bonesio658f29a2010-11-17 15:28:20 -080015extern void yyerror(char const *s);
Rob Herring47605972015-04-29 16:00:05 -050016#define ERROR(loc, ...) \
17 do { \
18 srcpos_error((loc), "Error", __VA_ARGS__); \
19 treesource_error = true; \
20 } while (0)
David Gibsona4da2e32007-12-18 15:06:42 +110021
Rob Herring0cec1142019-12-26 15:36:47 -070022#define YYERROR_CALL(msg) yyerror(msg)
23
Rob Herring6f05afc2017-01-04 10:45:20 -060024extern struct dt_info *parser_output;
Rob Herring47605972015-04-29 16:00:05 -050025extern bool treesource_error;
David Gibsona4da2e32007-12-18 15:06:42 +110026%}
27
28%union {
29 char *propnodename;
David Gibsona4da2e32007-12-18 15:06:42 +110030 char *labelref;
David Gibsoned95d742008-08-07 12:24:17 +100031 uint8_t byte;
David Gibsona4da2e32007-12-18 15:06:42 +110032 struct data data;
33
Stephen Warrencd296722012-09-28 21:25:59 +000034 struct {
35 struct data data;
36 int bits;
37 } array;
38
David Gibsona4da2e32007-12-18 15:06:42 +110039 struct property *prop;
40 struct property *proplist;
41 struct node *node;
42 struct node *nodelist;
43 struct reserve_info *re;
Stephen Warrencd296722012-09-28 21:25:59 +000044 uint64_t integer;
Rob Herring6f05afc2017-01-04 10:45:20 -060045 unsigned int flags;
David Gibsona4da2e32007-12-18 15:06:42 +110046}
47
48%token DT_V1
Rob Herring6f05afc2017-01-04 10:45:20 -060049%token DT_PLUGIN
David Gibsona4da2e32007-12-18 15:06:42 +110050%token DT_MEMRESERVE
Stephen Warrencd296722012-09-28 21:25:59 +000051%token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR
52%token DT_BITS
53%token DT_DEL_PROP
54%token DT_DEL_NODE
Rob Herring50aafd62018-05-08 13:07:49 -050055%token DT_OMIT_NO_REF
David Gibsona4da2e32007-12-18 15:06:42 +110056%token <propnodename> DT_PROPNODENAME
Rob Herring47605972015-04-29 16:00:05 -050057%token <integer> DT_LITERAL
58%token <integer> DT_CHAR_LITERAL
David Gibsona4da2e32007-12-18 15:06:42 +110059%token <byte> DT_BYTE
60%token <data> DT_STRING
61%token <labelref> DT_LABEL
Rob Herringc2e70752018-11-28 18:37:35 -060062%token <labelref> DT_LABEL_REF
63%token <labelref> DT_PATH_REF
David Gibsoned95d742008-08-07 12:24:17 +100064%token DT_INCBIN
David Gibsona4da2e32007-12-18 15:06:42 +110065
66%type <data> propdata
67%type <data> propdataprefix
Rob Herring6f05afc2017-01-04 10:45:20 -060068%type <flags> header
69%type <flags> headers
David Gibsona4da2e32007-12-18 15:06:42 +110070%type <re> memreserve
71%type <re> memreserves
Stephen Warrencd296722012-09-28 21:25:59 +000072%type <array> arrayprefix
David Gibsona4da2e32007-12-18 15:06:42 +110073%type <data> bytestring
74%type <prop> propdef
75%type <proplist> proplist
Rob Herringc2e70752018-11-28 18:37:35 -060076%type <labelref> dt_ref
David Gibsona4da2e32007-12-18 15:06:42 +110077
78%type <node> devicetree
79%type <node> nodedef
80%type <node> subnode
81%type <nodelist> subnodes
David Gibsona4da2e32007-12-18 15:06:42 +110082
Stephen Warrencd296722012-09-28 21:25:59 +000083%type <integer> integer_prim
84%type <integer> integer_unary
85%type <integer> integer_mul
86%type <integer> integer_add
87%type <integer> integer_shift
88%type <integer> integer_rela
89%type <integer> integer_eq
90%type <integer> integer_bitand
91%type <integer> integer_bitxor
92%type <integer> integer_bitor
93%type <integer> integer_and
94%type <integer> integer_or
95%type <integer> integer_trinary
96%type <integer> integer_expr
97
David Gibsona4da2e32007-12-18 15:06:42 +110098%%
99
100sourcefile:
Rob Herring6f05afc2017-01-04 10:45:20 -0600101 headers memreserves devicetree
David Gibsona4da2e32007-12-18 15:06:42 +1100102 {
Rob Herring6f05afc2017-01-04 10:45:20 -0600103 parser_output = build_dt_info($1, $2, $3,
104 guess_boot_cpuid($3));
105 }
106 ;
107
108header:
109 DT_V1 ';'
110 {
111 $$ = DTSF_V1;
112 }
113 | DT_V1 ';' DT_PLUGIN ';'
114 {
115 $$ = DTSF_V1 | DTSF_PLUGIN;
116 }
117 ;
118
119headers:
120 header
121 | header headers
122 {
123 if ($2 != $1)
124 ERROR(&@2, "Header flags don't match earlier ones");
125 $$ = $1;
David Gibsona4da2e32007-12-18 15:06:42 +1100126 }
127 ;
128
129memreserves:
130 /* empty */
131 {
132 $$ = NULL;
133 }
134 | memreserve memreserves
135 {
136 $$ = chain_reserve_entry($1, $2);
137 }
138 ;
139
140memreserve:
Stephen Warrencd296722012-09-28 21:25:59 +0000141 DT_MEMRESERVE integer_prim integer_prim ';'
David Gibsona4da2e32007-12-18 15:06:42 +1100142 {
John Bonesio658f29a2010-11-17 15:28:20 -0800143 $$ = build_reserve_entry($2, $3);
David Gibsona4da2e32007-12-18 15:06:42 +1100144 }
John Bonesio658f29a2010-11-17 15:28:20 -0800145 | DT_LABEL memreserve
David Gibsona4da2e32007-12-18 15:06:42 +1100146 {
John Bonesio658f29a2010-11-17 15:28:20 -0800147 add_label(&$2->labels, $1);
148 $$ = $2;
David Gibsona4da2e32007-12-18 15:06:42 +1100149 }
150 ;
151
Rob Herringc2e70752018-11-28 18:37:35 -0600152dt_ref: DT_LABEL_REF | DT_PATH_REF;
153
David Gibsona4da2e32007-12-18 15:06:42 +1100154devicetree:
155 '/' nodedef
156 {
John Bonesio658f29a2010-11-17 15:28:20 -0800157 $$ = name_node($2, "");
158 }
159 | devicetree '/' nodedef
160 {
161 $$ = merge_nodes($1, $3);
162 }
Rob Herringc2e70752018-11-28 18:37:35 -0600163 | dt_ref nodedef
Rob Herring9130ba82018-02-27 17:40:38 -0600164 {
165 /*
166 * We rely on the rule being always:
167 * versioninfo plugindecl memreserves devicetree
168 * so $-1 is what we want (plugindecl)
169 */
170 if (!($<flags>-1 & DTSF_PLUGIN))
171 ERROR(&@2, "Label or path %s not found", $1);
Rob Herringc2e70752018-11-28 18:37:35 -0600172 $$ = add_orphan_node(
173 name_node(build_node(NULL, NULL, NULL),
174 ""),
175 $2, $1);
Rob Herring9130ba82018-02-27 17:40:38 -0600176 }
Rob Herringc2e70752018-11-28 18:37:35 -0600177 | devicetree DT_LABEL dt_ref nodedef
Rob Herring47605972015-04-29 16:00:05 -0500178 {
179 struct node *target = get_node_by_ref($1, $3);
180
Rob Herring89d12312017-03-21 09:01:08 -0500181 if (target) {
182 add_label(&target->labels, $2);
Rob Herring47605972015-04-29 16:00:05 -0500183 merge_nodes(target, $4);
Rob Herring89d12312017-03-21 09:01:08 -0500184 } else
Rob Herring47605972015-04-29 16:00:05 -0500185 ERROR(&@3, "Label or path %s not found", $3);
186 $$ = $1;
187 }
Rob Herringc2e70752018-11-28 18:37:35 -0600188 | devicetree DT_PATH_REF nodedef
John Bonesio658f29a2010-11-17 15:28:20 -0800189 {
Rob Herring50aafd62018-05-08 13:07:49 -0500190 /*
191 * We rely on the rule being always:
192 * versioninfo plugindecl memreserves devicetree
193 * so $-1 is what we want (plugindecl)
194 */
195 if ($<flags>-1 & DTSF_PLUGIN) {
196 add_orphan_node($1, $3, $2);
Rob Herring4201d052017-10-03 11:37:04 -0500197 } else {
Rob Herring50aafd62018-05-08 13:07:49 -0500198 struct node *target = get_node_by_ref($1, $2);
199
200 if (target)
201 merge_nodes(target, $3);
Rob Herring4201d052017-10-03 11:37:04 -0500202 else
203 ERROR(&@2, "Label or path %s not found", $2);
204 }
John Bonesio658f29a2010-11-17 15:28:20 -0800205 $$ = $1;
David Gibsona4da2e32007-12-18 15:06:42 +1100206 }
Rob Herringc2e70752018-11-28 18:37:35 -0600207 | devicetree DT_LABEL_REF nodedef
208 {
209 struct node *target = get_node_by_ref($1, $2);
210
211 if (target) {
212 merge_nodes(target, $3);
213 } else {
214 /*
215 * We rely on the rule being always:
216 * versioninfo plugindecl memreserves devicetree
217 * so $-1 is what we want (plugindecl)
218 */
219 if ($<flags>-1 & DTSF_PLUGIN)
220 add_orphan_node($1, $3, $2);
221 else
222 ERROR(&@2, "Label or path %s not found", $2);
223 }
224 $$ = $1;
225 }
226 | devicetree DT_DEL_NODE dt_ref ';'
Stephen Warrencd296722012-09-28 21:25:59 +0000227 {
228 struct node *target = get_node_by_ref($1, $3);
229
Rob Herring47605972015-04-29 16:00:05 -0500230 if (target)
Stephen Warrencd296722012-09-28 21:25:59 +0000231 delete_node(target);
Rob Herring47605972015-04-29 16:00:05 -0500232 else
233 ERROR(&@3, "Label or path %s not found", $3);
234
Stephen Warrencd296722012-09-28 21:25:59 +0000235
236 $$ = $1;
237 }
Rob Herringc2e70752018-11-28 18:37:35 -0600238 | devicetree DT_OMIT_NO_REF dt_ref ';'
Rob Herring50aafd62018-05-08 13:07:49 -0500239 {
240 struct node *target = get_node_by_ref($1, $3);
241
242 if (target)
243 omit_node_if_unused(target);
244 else
245 ERROR(&@3, "Label or path %s not found", $3);
246
247
248 $$ = $1;
249 }
David Gibsona4da2e32007-12-18 15:06:42 +1100250 ;
251
252nodedef:
253 '{' proplist subnodes '}' ';'
254 {
Rob Herringc2e70752018-11-28 18:37:35 -0600255 $$ = build_node($2, $3, &@$);
David Gibsona4da2e32007-12-18 15:06:42 +1100256 }
257 ;
258
259proplist:
260 /* empty */
261 {
262 $$ = NULL;
263 }
264 | proplist propdef
265 {
266 $$ = chain_property($2, $1);
267 }
268 ;
269
270propdef:
John Bonesio658f29a2010-11-17 15:28:20 -0800271 DT_PROPNODENAME '=' propdata ';'
David Gibsona4da2e32007-12-18 15:06:42 +1100272 {
Rob Herringc2e70752018-11-28 18:37:35 -0600273 $$ = build_property($1, $3, &@$);
David Gibsona4da2e32007-12-18 15:06:42 +1100274 }
John Bonesio658f29a2010-11-17 15:28:20 -0800275 | DT_PROPNODENAME ';'
David Gibsona4da2e32007-12-18 15:06:42 +1100276 {
Rob Herringc2e70752018-11-28 18:37:35 -0600277 $$ = build_property($1, empty_data, &@$);
John Bonesio658f29a2010-11-17 15:28:20 -0800278 }
Stephen Warrencd296722012-09-28 21:25:59 +0000279 | DT_DEL_PROP DT_PROPNODENAME ';'
280 {
281 $$ = build_property_delete($2);
282 }
John Bonesio658f29a2010-11-17 15:28:20 -0800283 | DT_LABEL propdef
284 {
285 add_label(&$2->labels, $1);
286 $$ = $2;
David Gibsona4da2e32007-12-18 15:06:42 +1100287 }
288 ;
289
290propdata:
291 propdataprefix DT_STRING
292 {
293 $$ = data_merge($1, $2);
294 }
Stephen Warrencd296722012-09-28 21:25:59 +0000295 | propdataprefix arrayprefix '>'
David Gibsona4da2e32007-12-18 15:06:42 +1100296 {
Stephen Warrencd296722012-09-28 21:25:59 +0000297 $$ = data_merge($1, $2.data);
David Gibsona4da2e32007-12-18 15:06:42 +1100298 }
299 | propdataprefix '[' bytestring ']'
300 {
301 $$ = data_merge($1, $3);
302 }
Rob Herringc2e70752018-11-28 18:37:35 -0600303 | propdataprefix dt_ref
David Gibsona4da2e32007-12-18 15:06:42 +1100304 {
Rob Herringf8589272018-09-13 08:59:25 -0500305 $1 = data_add_marker($1, TYPE_STRING, $2);
David Gibsona4da2e32007-12-18 15:06:42 +1100306 $$ = data_add_marker($1, REF_PATH, $2);
307 }
Stephen Warrencd296722012-09-28 21:25:59 +0000308 | propdataprefix DT_INCBIN '(' DT_STRING ',' integer_prim ',' integer_prim ')'
David Gibsoned95d742008-08-07 12:24:17 +1000309 {
John Bonesio658f29a2010-11-17 15:28:20 -0800310 FILE *f = srcfile_relative_open($4.val, NULL);
311 struct data d;
David Gibsoned95d742008-08-07 12:24:17 +1000312
313 if ($6 != 0)
John Bonesio658f29a2010-11-17 15:28:20 -0800314 if (fseek(f, $6, SEEK_SET) != 0)
Rob Herring47605972015-04-29 16:00:05 -0500315 die("Couldn't seek to offset %llu in \"%s\": %s",
316 (unsigned long long)$6, $4.val,
317 strerror(errno));
David Gibsoned95d742008-08-07 12:24:17 +1000318
John Bonesio658f29a2010-11-17 15:28:20 -0800319 d = data_copy_file(f, $8);
David Gibsoned95d742008-08-07 12:24:17 +1000320
321 $$ = data_merge($1, d);
John Bonesio658f29a2010-11-17 15:28:20 -0800322 fclose(f);
David Gibsoned95d742008-08-07 12:24:17 +1000323 }
324 | propdataprefix DT_INCBIN '(' DT_STRING ')'
325 {
John Bonesio658f29a2010-11-17 15:28:20 -0800326 FILE *f = srcfile_relative_open($4.val, NULL);
David Gibsoned95d742008-08-07 12:24:17 +1000327 struct data d = empty_data;
328
John Bonesio658f29a2010-11-17 15:28:20 -0800329 d = data_copy_file(f, -1);
David Gibsoned95d742008-08-07 12:24:17 +1000330
331 $$ = data_merge($1, d);
John Bonesio658f29a2010-11-17 15:28:20 -0800332 fclose(f);
David Gibsoned95d742008-08-07 12:24:17 +1000333 }
David Gibsona4da2e32007-12-18 15:06:42 +1100334 | propdata DT_LABEL
335 {
336 $$ = data_add_marker($1, LABEL, $2);
337 }
338 ;
339
340propdataprefix:
341 /* empty */
342 {
343 $$ = empty_data;
344 }
345 | propdata ','
346 {
347 $$ = $1;
348 }
349 | propdataprefix DT_LABEL
350 {
351 $$ = data_add_marker($1, LABEL, $2);
352 }
353 ;
354
Stephen Warrencd296722012-09-28 21:25:59 +0000355arrayprefix:
356 DT_BITS DT_LITERAL '<'
David Gibsona4da2e32007-12-18 15:06:42 +1100357 {
Rob Herring47605972015-04-29 16:00:05 -0500358 unsigned long long bits;
Rob Herringf8589272018-09-13 08:59:25 -0500359 enum markertype type = TYPE_UINT32;
Stephen Warrencd296722012-09-28 21:25:59 +0000360
Rob Herring47605972015-04-29 16:00:05 -0500361 bits = $2;
362
Rob Herringf8589272018-09-13 08:59:25 -0500363 switch (bits) {
364 case 8: type = TYPE_UINT8; break;
365 case 16: type = TYPE_UINT16; break;
366 case 32: type = TYPE_UINT32; break;
367 case 64: type = TYPE_UINT64; break;
368 default:
Rob Herring47605972015-04-29 16:00:05 -0500369 ERROR(&@2, "Array elements must be"
370 " 8, 16, 32 or 64-bits");
371 bits = 32;
Stephen Warrencd296722012-09-28 21:25:59 +0000372 }
Rob Herring47605972015-04-29 16:00:05 -0500373
Rob Herringf8589272018-09-13 08:59:25 -0500374 $$.data = data_add_marker(empty_data, type, NULL);
Rob Herring47605972015-04-29 16:00:05 -0500375 $$.bits = bits;
David Gibsona4da2e32007-12-18 15:06:42 +1100376 }
Stephen Warrencd296722012-09-28 21:25:59 +0000377 | '<'
David Gibsona4da2e32007-12-18 15:06:42 +1100378 {
Rob Herringf8589272018-09-13 08:59:25 -0500379 $$.data = data_add_marker(empty_data, TYPE_UINT32, NULL);
Stephen Warrencd296722012-09-28 21:25:59 +0000380 $$.bits = 32;
David Gibsona4da2e32007-12-18 15:06:42 +1100381 }
Stephen Warrencd296722012-09-28 21:25:59 +0000382 | arrayprefix integer_prim
David Gibsona4da2e32007-12-18 15:06:42 +1100383 {
Stephen Warrencd296722012-09-28 21:25:59 +0000384 if ($1.bits < 64) {
385 uint64_t mask = (1ULL << $1.bits) - 1;
386 /*
387 * Bits above mask must either be all zero
388 * (positive within range of mask) or all one
389 * (negative and sign-extended). The second
390 * condition is true if when we set all bits
391 * within the mask to one (i.e. | in the
392 * mask), all bits are one.
393 */
394 if (($2 > mask) && (($2 | mask) != -1ULL))
Rob Herring47605972015-04-29 16:00:05 -0500395 ERROR(&@2, "Value out of range for"
396 " %d-bit array element", $1.bits);
Stephen Warrencd296722012-09-28 21:25:59 +0000397 }
398
399 $$.data = data_append_integer($1.data, $2, $1.bits);
David Gibsona4da2e32007-12-18 15:06:42 +1100400 }
Rob Herringc2e70752018-11-28 18:37:35 -0600401 | arrayprefix dt_ref
David Gibsona4da2e32007-12-18 15:06:42 +1100402 {
Stephen Warrencd296722012-09-28 21:25:59 +0000403 uint64_t val = ~0ULL >> (64 - $1.bits);
404
405 if ($1.bits == 32)
406 $1.data = data_add_marker($1.data,
407 REF_PHANDLE,
408 $2);
409 else
Rob Herring47605972015-04-29 16:00:05 -0500410 ERROR(&@2, "References are only allowed in "
Stephen Warrencd296722012-09-28 21:25:59 +0000411 "arrays with 32-bit elements.");
412
413 $$.data = data_append_integer($1.data, val, $1.bits);
414 }
415 | arrayprefix DT_LABEL
416 {
417 $$.data = data_add_marker($1.data, LABEL, $2);
David Gibsona4da2e32007-12-18 15:06:42 +1100418 }
419 ;
420
Stephen Warrencd296722012-09-28 21:25:59 +0000421integer_prim:
David Gibsona4da2e32007-12-18 15:06:42 +1100422 DT_LITERAL
Stephen Warrencd296722012-09-28 21:25:59 +0000423 | DT_CHAR_LITERAL
Stephen Warrencd296722012-09-28 21:25:59 +0000424 | '(' integer_expr ')'
425 {
426 $$ = $2;
427 }
428 ;
429
430integer_expr:
431 integer_trinary
432 ;
433
434integer_trinary:
435 integer_or
436 | integer_or '?' integer_expr ':' integer_trinary { $$ = $1 ? $3 : $5; }
437 ;
438
439integer_or:
440 integer_and
441 | integer_or DT_OR integer_and { $$ = $1 || $3; }
442 ;
443
444integer_and:
445 integer_bitor
446 | integer_and DT_AND integer_bitor { $$ = $1 && $3; }
447 ;
448
449integer_bitor:
450 integer_bitxor
451 | integer_bitor '|' integer_bitxor { $$ = $1 | $3; }
452 ;
453
454integer_bitxor:
455 integer_bitand
456 | integer_bitxor '^' integer_bitand { $$ = $1 ^ $3; }
457 ;
458
459integer_bitand:
460 integer_eq
461 | integer_bitand '&' integer_eq { $$ = $1 & $3; }
462 ;
463
464integer_eq:
465 integer_rela
466 | integer_eq DT_EQ integer_rela { $$ = $1 == $3; }
467 | integer_eq DT_NE integer_rela { $$ = $1 != $3; }
468 ;
469
470integer_rela:
471 integer_shift
472 | integer_rela '<' integer_shift { $$ = $1 < $3; }
473 | integer_rela '>' integer_shift { $$ = $1 > $3; }
474 | integer_rela DT_LE integer_shift { $$ = $1 <= $3; }
475 | integer_rela DT_GE integer_shift { $$ = $1 >= $3; }
476 ;
477
478integer_shift:
Rob Herring6e9c9682020-10-12 09:58:15 -0500479 integer_shift DT_LSHIFT integer_add { $$ = ($3 < 64) ? ($1 << $3) : 0; }
480 | integer_shift DT_RSHIFT integer_add { $$ = ($3 < 64) ? ($1 >> $3) : 0; }
Stephen Warrencd296722012-09-28 21:25:59 +0000481 | integer_add
482 ;
483
484integer_add:
485 integer_add '+' integer_mul { $$ = $1 + $3; }
486 | integer_add '-' integer_mul { $$ = $1 - $3; }
487 | integer_mul
488 ;
489
490integer_mul:
491 integer_mul '*' integer_unary { $$ = $1 * $3; }
Rob Herring91feabc2016-01-26 09:04:11 -0600492 | integer_mul '/' integer_unary
493 {
494 if ($3 != 0) {
495 $$ = $1 / $3;
496 } else {
497 ERROR(&@$, "Division by zero");
498 $$ = 0;
499 }
500 }
501 | integer_mul '%' integer_unary
502 {
503 if ($3 != 0) {
504 $$ = $1 % $3;
505 } else {
506 ERROR(&@$, "Division by zero");
507 $$ = 0;
508 }
509 }
Stephen Warrencd296722012-09-28 21:25:59 +0000510 | integer_unary
511 ;
512
513integer_unary:
514 integer_prim
515 | '-' integer_unary { $$ = -$2; }
516 | '~' integer_unary { $$ = ~$2; }
517 | '!' integer_unary { $$ = !$2; }
David Gibsona4da2e32007-12-18 15:06:42 +1100518 ;
519
520bytestring:
521 /* empty */
522 {
Rob Herringf8589272018-09-13 08:59:25 -0500523 $$ = data_add_marker(empty_data, TYPE_UINT8, NULL);
David Gibsona4da2e32007-12-18 15:06:42 +1100524 }
525 | bytestring DT_BYTE
526 {
527 $$ = data_append_byte($1, $2);
528 }
529 | bytestring DT_LABEL
530 {
531 $$ = data_add_marker($1, LABEL, $2);
532 }
533 ;
534
535subnodes:
536 /* empty */
537 {
538 $$ = NULL;
539 }
John Bonesio658f29a2010-11-17 15:28:20 -0800540 | subnode subnodes
David Gibsona4da2e32007-12-18 15:06:42 +1100541 {
542 $$ = chain_node($1, $2);
543 }
544 | subnode propdef
545 {
Rob Herring47605972015-04-29 16:00:05 -0500546 ERROR(&@2, "Properties must precede subnodes");
David Gibsona4da2e32007-12-18 15:06:42 +1100547 YYERROR;
548 }
549 ;
550
551subnode:
John Bonesio658f29a2010-11-17 15:28:20 -0800552 DT_PROPNODENAME nodedef
David Gibsona4da2e32007-12-18 15:06:42 +1100553 {
John Bonesio658f29a2010-11-17 15:28:20 -0800554 $$ = name_node($2, $1);
David Gibsona4da2e32007-12-18 15:06:42 +1100555 }
Stephen Warrencd296722012-09-28 21:25:59 +0000556 | DT_DEL_NODE DT_PROPNODENAME ';'
557 {
Rob Herringc2e70752018-11-28 18:37:35 -0600558 $$ = name_node(build_node_delete(&@$), $2);
Stephen Warrencd296722012-09-28 21:25:59 +0000559 }
Rob Herring50aafd62018-05-08 13:07:49 -0500560 | DT_OMIT_NO_REF subnode
561 {
562 $$ = omit_node_if_unused($2);
563 }
John Bonesio658f29a2010-11-17 15:28:20 -0800564 | DT_LABEL subnode
David Gibsona4da2e32007-12-18 15:06:42 +1100565 {
John Bonesio658f29a2010-11-17 15:28:20 -0800566 add_label(&$2->labels, $1);
567 $$ = $2;
David Gibsona4da2e32007-12-18 15:06:42 +1100568 }
569 ;
570
571%%
572
Rob Herring47605972015-04-29 16:00:05 -0500573void yyerror(char const *s)
David Gibsona4da2e32007-12-18 15:06:42 +1100574{
Rob Herring47605972015-04-29 16:00:05 -0500575 ERROR(&yylloc, "%s", s);
Stephen Warrencd296722012-09-28 21:25:59 +0000576}