blob: 40dcf4f149dad647364ad1a3912f4333a79c0a82 [file] [log] [blame]
Rob Herringacfe84f2019-06-20 15:19:38 -06001// SPDX-License-Identifier: GPL-2.0-or-later
David Gibsonfc14dad2005-06-08 17:18:34 +10002/*
3 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
David Gibsonfc14dad2005-06-08 17:18:34 +10004 */
Ethan Sommer71502862019-10-29 12:26:19 -04005%locations
6
David Gibsonfc14dad2005-06-08 17:18:34 +10007%{
David Gibsone37ec7d2008-06-11 11:58:39 +10008#include <stdio.h>
Pantelis Antoniou20f29d82016-12-07 14:48:18 +02009#include <inttypes.h>
David Gibsone37ec7d2008-06-11 11:58:39 +100010
David Gibsonfc14dad2005-06-08 17:18:34 +100011#include "dtc.h"
Jon Loeligere45e6fd2007-03-23 15:18:41 -050012#include "srcpos.h"
David Gibsonfc14dad2005-06-08 17:18:34 +100013
David Gibson6b8e0562008-03-05 11:47:54 +110014extern int yylex(void);
Jon Loeligere5c8e1d2008-09-12 13:39:49 -050015extern void yyerror(char const *s);
David Gibsonfa3f3f02014-01-03 23:57:39 +110016#define ERROR(loc, ...) \
17 do { \
18 srcpos_error((loc), "Error", __VA_ARGS__); \
19 treesource_error = true; \
20 } while (0)
David Gibsonfc14dad2005-06-08 17:18:34 +100021
Ethan Sommer71502862019-10-29 12:26:19 -040022#define YYERROR_CALL(msg) yyerror(msg)
23
David Gibson00fbb862016-05-31 11:58:42 +100024extern struct dt_info *parser_output;
David Gibson17625372013-10-28 21:06:53 +110025extern bool treesource_error;
David Gibsonfc14dad2005-06-08 17:18:34 +100026%}
27
28%union {
David Gibson9ed27a22007-11-07 11:16:19 +110029 char *propnodename;
David Gibson9ed27a22007-11-07 11:16:19 +110030 char *labelref;
David Gibson53359012008-06-25 13:53:07 +100031 uint8_t byte;
David Gibsonfc14dad2005-06-08 17:18:34 +100032 struct data data;
David Gibson9ed27a22007-11-07 11:16:19 +110033
Anton Staaf033089f2011-10-11 10:22:29 -070034 struct {
35 struct data data;
36 int bits;
37 } array;
38
David Gibsonfc14dad2005-06-08 17:18:34 +100039 struct property *prop;
40 struct property *proplist;
41 struct node *node;
42 struct node *nodelist;
David Gibsonf040d952005-10-24 18:18:38 +100043 struct reserve_info *re;
Stephen Warren5f0c3b22012-04-03 20:56:00 -060044 uint64_t integer;
Pantelis Antoniou20f29d82016-12-07 14:48:18 +020045 unsigned int flags;
David Gibsonfc14dad2005-06-08 17:18:34 +100046}
47
David Gibson9138db52007-11-07 11:17:17 +110048%token DT_V1
Pantelis Antoniou20f29d82016-12-07 14:48:18 +020049%token DT_PLUGIN
David Gibsonf0517db2005-07-15 17:14:24 +100050%token DT_MEMRESERVE
Stephen Warren5f0c3b22012-04-03 20:56:00 -060051%token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR
Anton Staaf033089f2011-10-11 10:22:29 -070052%token DT_BITS
Stephen Warren45013d82012-08-07 22:50:15 -060053%token DT_DEL_PROP
54%token DT_DEL_NODE
Maxime Ripard4038fd92018-05-03 22:27:26 +020055%token DT_OMIT_NO_REF
David Gibson9ed27a22007-11-07 11:16:19 +110056%token <propnodename> DT_PROPNODENAME
David Gibsonb82b9772014-01-03 20:00:01 +110057%token <integer> DT_LITERAL
David Gibsoncfc65232014-01-04 10:03:55 +110058%token <integer> DT_CHAR_LITERAL
David Gibsonfc14dad2005-06-08 17:18:34 +100059%token <byte> DT_BYTE
60%token <data> DT_STRING
David Gibson9ed27a22007-11-07 11:16:19 +110061%token <labelref> DT_LABEL
Fredrik Markstrom0fcffda2018-09-24 13:27:27 +020062%token <labelref> DT_LABEL_REF
63%token <labelref> DT_PATH_REF
David Gibsone37ec7d2008-06-11 11:58:39 +100064%token DT_INCBIN
David Gibsonfc14dad2005-06-08 17:18:34 +100065
66%type <data> propdata
David Gibson32da4752007-02-07 16:37:50 +110067%type <data> propdataprefix
David Gibson1ef86ad2016-12-09 16:23:23 +110068%type <flags> header
69%type <flags> headers
David Gibsonf0517db2005-07-15 17:14:24 +100070%type <re> memreserve
David Gibsonf040d952005-10-24 18:18:38 +100071%type <re> memreserves
Anton Staaf033089f2011-10-11 10:22:29 -070072%type <array> arrayprefix
David Gibsonfc14dad2005-06-08 17:18:34 +100073%type <data> bytestring
74%type <prop> propdef
75%type <proplist> proplist
Fredrik Markstrom0fcffda2018-09-24 13:27:27 +020076%type <labelref> dt_ref
David Gibsonfc14dad2005-06-08 17:18:34 +100077
David Gibsonf0517db2005-07-15 17:14:24 +100078%type <node> devicetree
David Gibsonfc14dad2005-06-08 17:18:34 +100079%type <node> nodedef
80%type <node> subnode
81%type <nodelist> subnodes
David Gibson4102d842005-06-16 14:36:37 +100082
Stephen Warren5f0c3b22012-04-03 20:56:00 -060083%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 Gibsonfc14dad2005-06-08 17:18:34 +100098%%
99
Jon Loeliger30807ca2007-10-18 09:42:16 -0500100sourcefile:
David Gibson1ef86ad2016-12-09 16:23:23 +1100101 headers memreserves devicetree
David Gibson9138db52007-11-07 11:17:17 +1100102 {
David Gibson00fbb862016-05-31 11:58:42 +1000103 parser_output = build_dt_info($1, $2, $3,
104 guess_boot_cpuid($3));
Pantelis Antoniou20f29d82016-12-07 14:48:18 +0200105 }
106 ;
107
David Gibson1ef86ad2016-12-09 16:23:23 +1100108header:
109 DT_V1 ';'
Pantelis Antoniou20f29d82016-12-07 14:48:18 +0200110 {
111 $$ = DTSF_V1;
David Gibson9138db52007-11-07 11:17:17 +1100112 }
David Gibson1ef86ad2016-12-09 16:23:23 +1100113 | DT_V1 ';' DT_PLUGIN ';'
114 {
115 $$ = DTSF_V1 | DTSF_PLUGIN;
116 }
David Gibsonf0517db2005-07-15 17:14:24 +1000117 ;
118
David Gibson1ef86ad2016-12-09 16:23:23 +1100119headers:
120 header
121 | header headers
Pantelis Antoniou20f29d82016-12-07 14:48:18 +0200122 {
David Gibson1ef86ad2016-12-09 16:23:23 +1100123 if ($2 != $1)
124 ERROR(&@2, "Header flags don't match earlier ones");
125 $$ = $1;
Pantelis Antoniou20f29d82016-12-07 14:48:18 +0200126 }
David Gibsonc4cb12e2014-06-02 15:23:40 +1000127 ;
128
Jon Loeliger30807ca2007-10-18 09:42:16 -0500129memreserves:
Jon Loeliger56412892007-10-23 09:28:54 -0500130 /* empty */
Jon Loeliger30807ca2007-10-18 09:42:16 -0500131 {
David Gibsonf040d952005-10-24 18:18:38 +1000132 $$ = NULL;
David Gibsonf0517db2005-07-15 17:14:24 +1000133 }
Jon Loeliger56412892007-10-23 09:28:54 -0500134 | memreserve memreserves
135 {
136 $$ = chain_reserve_entry($1, $2);
137 }
David Gibsonf0517db2005-07-15 17:14:24 +1000138 ;
139
Jon Loeliger30807ca2007-10-18 09:42:16 -0500140memreserve:
Stephen Warren5f0c3b22012-04-03 20:56:00 -0600141 DT_MEMRESERVE integer_prim integer_prim ';'
Jon Loeliger30807ca2007-10-18 09:42:16 -0500142 {
David Gibson05898c62010-02-24 18:22:17 +1100143 $$ = build_reserve_entry($2, $3);
144 }
145 | DT_LABEL memreserve
146 {
147 add_label(&$2->labels, $1);
148 $$ = $2;
David Gibsonf0517db2005-07-15 17:14:24 +1000149 }
David Gibson9138db52007-11-07 11:17:17 +1100150 ;
151
Fredrik Markstrom0fcffda2018-09-24 13:27:27 +0200152dt_ref: DT_LABEL_REF | DT_PATH_REF;
153
Jon Loeliger30807ca2007-10-18 09:42:16 -0500154devicetree:
155 '/' nodedef
156 {
David Gibson05898c62010-02-24 18:22:17 +1100157 $$ = name_node($2, "");
David Gibsonf0517db2005-07-15 17:14:24 +1000158 }
David Gibson8773e122010-09-20 16:33:34 -0600159 | devicetree '/' nodedef
160 {
161 $$ = merge_nodes($1, $3);
162 }
Fredrik Markstrom0fcffda2018-09-24 13:27:27 +0200163 | dt_ref nodedef
Grant Likelyb260c4f2017-11-20 17:12:18 +0000164 {
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);
Julia Lawall8e20ccf2018-11-16 17:29:59 +0100172 $$ = add_orphan_node(
173 name_node(build_node(NULL, NULL, NULL),
174 ""),
175 $2, $1);
Grant Likelyb260c4f2017-11-20 17:12:18 +0000176 }
Fredrik Markstrom0fcffda2018-09-24 13:27:27 +0200177 | devicetree DT_LABEL dt_ref nodedef
Nikhil Devshatwar3346e062015-02-23 12:29:19 +1100178 {
179 struct node *target = get_node_by_ref($1, $3);
180
Stephen Boyd3b9c9702017-01-30 14:06:17 -0800181 if (target) {
182 add_label(&target->labels, $2);
Nikhil Devshatwar3346e062015-02-23 12:29:19 +1100183 merge_nodes(target, $4);
Stephen Boyd3b9c9702017-01-30 14:06:17 -0800184 } else
Nikhil Devshatwar3346e062015-02-23 12:29:19 +1100185 ERROR(&@3, "Label or path %s not found", $3);
186 $$ = $1;
187 }
Fredrik Markstrom0fcffda2018-09-24 13:27:27 +0200188 | devicetree DT_PATH_REF nodedef
David Gibson8773e122010-09-20 16:33:34 -0600189 {
David Gibson8f1b35f2018-03-06 13:27:53 +1100190 /*
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);
Pantelis Antoniou737b2df2017-06-14 17:53:05 +0300197 } else {
David Gibson8f1b35f2018-03-06 13:27:53 +1100198 struct node *target = get_node_by_ref($1, $2);
199
200 if (target)
201 merge_nodes(target, $3);
Pantelis Antoniou737b2df2017-06-14 17:53:05 +0300202 else
203 ERROR(&@2, "Label or path %s not found", $2);
204 }
David Gibson8773e122010-09-20 16:33:34 -0600205 $$ = $1;
206 }
Fredrik Markstrom0fcffda2018-09-24 13:27:27 +0200207 | 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 Warren45013d82012-08-07 22:50:15 -0600227 {
228 struct node *target = get_node_by_ref($1, $3);
229
David Gibsonfa3f3f02014-01-03 23:57:39 +1100230 if (target)
Stephen Warren45013d82012-08-07 22:50:15 -0600231 delete_node(target);
David Gibsonfa3f3f02014-01-03 23:57:39 +1100232 else
233 ERROR(&@3, "Label or path %s not found", $3);
234
Stephen Warren45013d82012-08-07 22:50:15 -0600235
236 $$ = $1;
237 }
Fredrik Markstrom0fcffda2018-09-24 13:27:27 +0200238 | devicetree DT_OMIT_NO_REF dt_ref ';'
Maxime Ripard4038fd92018-05-03 22:27:26 +0200239 {
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 Gibsonfc14dad2005-06-08 17:18:34 +1000250 ;
251
Jon Loeliger30807ca2007-10-18 09:42:16 -0500252nodedef:
253 '{' proplist subnodes '}' ';'
254 {
Julia Lawall8e20ccf2018-11-16 17:29:59 +0100255 $$ = build_node($2, $3, &@$);
David Gibsonfc14dad2005-06-08 17:18:34 +1000256 }
257 ;
258
Jon Loeliger30807ca2007-10-18 09:42:16 -0500259proplist:
Jon Loeliger56412892007-10-23 09:28:54 -0500260 /* empty */
Jon Loeliger30807ca2007-10-18 09:42:16 -0500261 {
David Gibsonfc14dad2005-06-08 17:18:34 +1000262 $$ = NULL;
263 }
Jon Loeliger7b3fb782007-10-22 16:09:56 -0500264 | proplist propdef
Jon Loeliger56412892007-10-23 09:28:54 -0500265 {
Jon Loeliger7b3fb782007-10-22 16:09:56 -0500266 $$ = chain_property($2, $1);
Jon Loeliger56412892007-10-23 09:28:54 -0500267 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000268 ;
269
Jon Loeliger30807ca2007-10-18 09:42:16 -0500270propdef:
David Gibson05898c62010-02-24 18:22:17 +1100271 DT_PROPNODENAME '=' propdata ';'
Jon Loeliger30807ca2007-10-18 09:42:16 -0500272 {
Julia Lawall8e20ccf2018-11-16 17:29:59 +0100273 $$ = build_property($1, $3, &@$);
David Gibsonfc14dad2005-06-08 17:18:34 +1000274 }
David Gibson05898c62010-02-24 18:22:17 +1100275 | DT_PROPNODENAME ';'
Jon Loeliger30807ca2007-10-18 09:42:16 -0500276 {
Julia Lawall8e20ccf2018-11-16 17:29:59 +0100277 $$ = build_property($1, empty_data, &@$);
David Gibson05898c62010-02-24 18:22:17 +1100278 }
Stephen Warren45013d82012-08-07 22:50:15 -0600279 | DT_DEL_PROP DT_PROPNODENAME ';'
280 {
281 $$ = build_property_delete($2);
282 }
David Gibson05898c62010-02-24 18:22:17 +1100283 | DT_LABEL propdef
284 {
285 add_label(&$2->labels, $1);
286 $$ = $2;
David Gibsonfc14dad2005-06-08 17:18:34 +1000287 }
288 ;
289
Jon Loeliger30807ca2007-10-18 09:42:16 -0500290propdata:
291 propdataprefix DT_STRING
292 {
293 $$ = data_merge($1, $2);
David Gibson32da4752007-02-07 16:37:50 +1100294 }
Anton Staaf033089f2011-10-11 10:22:29 -0700295 | propdataprefix arrayprefix '>'
Jon Loeliger30807ca2007-10-18 09:42:16 -0500296 {
Anton Staaf033089f2011-10-11 10:22:29 -0700297 $$ = data_merge($1, $2.data);
Jon Loeliger30807ca2007-10-18 09:42:16 -0500298 }
299 | propdataprefix '[' bytestring ']'
300 {
301 $$ = data_merge($1, $3);
302 }
Fredrik Markstrom0fcffda2018-09-24 13:27:27 +0200303 | propdataprefix dt_ref
David Gibsonefbbef82007-12-05 10:43:50 +1100304 {
Rob Herringac68ff92018-07-30 21:57:35 -0600305 $1 = data_add_marker($1, TYPE_STRING, $2);
David Gibsonefbbef82007-12-05 10:43:50 +1100306 $$ = data_add_marker($1, REF_PATH, $2);
307 }
Stephen Warren5f0c3b22012-04-03 20:56:00 -0600308 | propdataprefix DT_INCBIN '(' DT_STRING ',' integer_prim ',' integer_prim ')'
David Gibsone37ec7d2008-06-11 11:58:39 +1000309 {
David Gibsond68cb362009-12-08 14:24:42 +1100310 FILE *f = srcfile_relative_open($4.val, NULL);
311 struct data d;
David Gibsone37ec7d2008-06-11 11:58:39 +1000312
313 if ($6 != 0)
David Gibsond68cb362009-12-08 14:24:42 +1100314 if (fseek(f, $6, SEEK_SET) != 0)
David Gibson6a15eb22014-01-04 10:04:19 +1100315 die("Couldn't seek to offset %llu in \"%s\": %s",
316 (unsigned long long)$6, $4.val,
317 strerror(errno));
David Gibsone37ec7d2008-06-11 11:58:39 +1000318
David Gibsond68cb362009-12-08 14:24:42 +1100319 d = data_copy_file(f, $8);
David Gibsone37ec7d2008-06-11 11:58:39 +1000320
321 $$ = data_merge($1, d);
David Gibsond68cb362009-12-08 14:24:42 +1100322 fclose(f);
David Gibsone37ec7d2008-06-11 11:58:39 +1000323 }
324 | propdataprefix DT_INCBIN '(' DT_STRING ')'
325 {
David Gibsond68cb362009-12-08 14:24:42 +1100326 FILE *f = srcfile_relative_open($4.val, NULL);
David Gibsone37ec7d2008-06-11 11:58:39 +1000327 struct data d = empty_data;
328
David Gibsond68cb362009-12-08 14:24:42 +1100329 d = data_copy_file(f, -1);
David Gibsone37ec7d2008-06-11 11:58:39 +1000330
331 $$ = data_merge($1, d);
David Gibsond68cb362009-12-08 14:24:42 +1100332 fclose(f);
David Gibsone37ec7d2008-06-11 11:58:39 +1000333 }
Jon Loeliger30807ca2007-10-18 09:42:16 -0500334 | propdata DT_LABEL
335 {
David Gibsondc941772007-11-22 14:39:23 +1100336 $$ = data_add_marker($1, LABEL, $2);
Jon Loeliger30807ca2007-10-18 09:42:16 -0500337 }
David Gibson32da4752007-02-07 16:37:50 +1100338 ;
339
Jon Loeliger30807ca2007-10-18 09:42:16 -0500340propdataprefix:
Jon Loeliger56412892007-10-23 09:28:54 -0500341 /* empty */
342 {
343 $$ = empty_data;
344 }
345 | propdata ','
Jon Loeliger30807ca2007-10-18 09:42:16 -0500346 {
347 $$ = $1;
348 }
349 | propdataprefix DT_LABEL
350 {
David Gibsondc941772007-11-22 14:39:23 +1100351 $$ = data_add_marker($1, LABEL, $2);
Jon Loeliger30807ca2007-10-18 09:42:16 -0500352 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000353 ;
354
Anton Staaf033089f2011-10-11 10:22:29 -0700355arrayprefix:
356 DT_BITS DT_LITERAL '<'
Jon Loeliger56412892007-10-23 09:28:54 -0500357 {
David Gibsonb82b9772014-01-03 20:00:01 +1100358 unsigned long long bits;
Grant Likely44d3efe2018-05-15 17:42:54 -0500359 enum markertype type = TYPE_UINT32;
David Gibsonfc14dad2005-06-08 17:18:34 +1000360
David Gibsonb82b9772014-01-03 20:00:01 +1100361 bits = $2;
362
Grant Likely44d3efe2018-05-15 17:42:54 -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:
David Gibsonfa3f3f02014-01-03 23:57:39 +1100369 ERROR(&@2, "Array elements must be"
370 " 8, 16, 32 or 64-bits");
David Gibsonb82b9772014-01-03 20:00:01 +1100371 bits = 32;
Anton Staaf033089f2011-10-11 10:22:29 -0700372 }
David Gibsonb82b9772014-01-03 20:00:01 +1100373
Grant Likely44d3efe2018-05-15 17:42:54 -0500374 $$.data = data_add_marker(empty_data, type, NULL);
David Gibsonb82b9772014-01-03 20:00:01 +1100375 $$.bits = bits;
David Gibson9138db52007-11-07 11:17:17 +1100376 }
Anton Staaf033089f2011-10-11 10:22:29 -0700377 | '<'
Anton Staafa4ea2fa2011-09-09 12:16:30 -0700378 {
Grant Likely44d3efe2018-05-15 17:42:54 -0500379 $$.data = data_add_marker(empty_data, TYPE_UINT32, NULL);
Anton Staaf033089f2011-10-11 10:22:29 -0700380 $$.bits = 32;
381 }
Stephen Warren5f0c3b22012-04-03 20:56:00 -0600382 | arrayprefix integer_prim
Anton Staaf033089f2011-10-11 10:22:29 -0700383 {
Stephen Warren5f0c3b22012-04-03 20:56:00 -0600384 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))
David Gibsonfa3f3f02014-01-03 23:57:39 +1100395 ERROR(&@2, "Value out of range for"
396 " %d-bit array element", $1.bits);
Stephen Warren5f0c3b22012-04-03 20:56:00 -0600397 }
Anton Staaf033089f2011-10-11 10:22:29 -0700398
Stephen Warren5f0c3b22012-04-03 20:56:00 -0600399 $$.data = data_append_integer($1.data, $2, $1.bits);
Anton Staaf033089f2011-10-11 10:22:29 -0700400 }
Fredrik Markstrom0fcffda2018-09-24 13:27:27 +0200401 | arrayprefix dt_ref
Anton Staaf033089f2011-10-11 10:22:29 -0700402 {
403 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
David Gibsonfa3f3f02014-01-03 23:57:39 +1100410 ERROR(&@2, "References are only allowed in "
Anton Staaf033089f2011-10-11 10:22:29 -0700411 "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);
Anton Staafa4ea2fa2011-09-09 12:16:30 -0700418 }
David Gibson9ed27a22007-11-07 11:16:19 +1100419 ;
420
Stephen Warren5f0c3b22012-04-03 20:56:00 -0600421integer_prim:
422 DT_LITERAL
Stephen Warren5f0c3b22012-04-03 20:56:00 -0600423 | DT_CHAR_LITERAL
Stephen Warren5f0c3b22012-04-03 20:56:00 -0600424 | '(' 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:
479 integer_shift DT_LSHIFT integer_add { $$ = $1 << $3; }
480 | integer_shift DT_RSHIFT integer_add { $$ = $1 >> $3; }
481 | 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; }
David Gibson19370952016-01-03 22:27:32 +1100492 | integer_mul '/' integer_unary
493 {
494 if ($3 != 0) {
495 $$ = $1 / $3;
496 } else {
497 ERROR(&@$, "Division by zero");
498 $$ = 0;
499 }
500 }
David Gibsonb06e55c2016-01-12 19:27:25 +1100501 | integer_mul '%' integer_unary
502 {
503 if ($3 != 0) {
504 $$ = $1 % $3;
505 } else {
506 ERROR(&@$, "Division by zero");
507 $$ = 0;
508 }
509 }
Stephen Warren5f0c3b22012-04-03 20:56:00 -0600510 | integer_unary
511 ;
512
513integer_unary:
514 integer_prim
515 | '-' integer_unary { $$ = -$2; }
516 | '~' integer_unary { $$ = ~$2; }
517 | '!' integer_unary { $$ = !$2; }
518 ;
519
Jon Loeliger30807ca2007-10-18 09:42:16 -0500520bytestring:
Jon Loeliger56412892007-10-23 09:28:54 -0500521 /* empty */
522 {
Grant Likely44d3efe2018-05-15 17:42:54 -0500523 $$ = data_add_marker(empty_data, TYPE_UINT8, NULL);
Jon Loeliger56412892007-10-23 09:28:54 -0500524 }
525 | bytestring DT_BYTE
Jon Loeliger30807ca2007-10-18 09:42:16 -0500526 {
527 $$ = data_append_byte($1, $2);
528 }
529 | bytestring DT_LABEL
530 {
David Gibsondc941772007-11-22 14:39:23 +1100531 $$ = data_add_marker($1, LABEL, $2);
Jon Loeliger30807ca2007-10-18 09:42:16 -0500532 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000533 ;
534
Jon Loeliger30807ca2007-10-18 09:42:16 -0500535subnodes:
Jon Loeliger56412892007-10-23 09:28:54 -0500536 /* empty */
Jon Loeliger30807ca2007-10-18 09:42:16 -0500537 {
538 $$ = NULL;
539 }
David Gibson05898c62010-02-24 18:22:17 +1100540 | subnode subnodes
Jon Loeliger56412892007-10-23 09:28:54 -0500541 {
542 $$ = chain_node($1, $2);
543 }
David Gibsonc0481022007-12-05 10:27:04 +1100544 | subnode propdef
545 {
David Gibsonfa3f3f02014-01-03 23:57:39 +1100546 ERROR(&@2, "Properties must precede subnodes");
David Gibsonc0481022007-12-05 10:27:04 +1100547 YYERROR;
548 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000549 ;
550
Jon Loeliger30807ca2007-10-18 09:42:16 -0500551subnode:
David Gibson05898c62010-02-24 18:22:17 +1100552 DT_PROPNODENAME nodedef
Jon Loeliger30807ca2007-10-18 09:42:16 -0500553 {
David Gibson05898c62010-02-24 18:22:17 +1100554 $$ = name_node($2, $1);
Jon Loeliger30807ca2007-10-18 09:42:16 -0500555 }
Stephen Warren45013d82012-08-07 22:50:15 -0600556 | DT_DEL_NODE DT_PROPNODENAME ';'
557 {
Julia Lawall8e20ccf2018-11-16 17:29:59 +0100558 $$ = name_node(build_node_delete(&@$), $2);
Stephen Warren45013d82012-08-07 22:50:15 -0600559 }
Maxime Ripard4038fd92018-05-03 22:27:26 +0200560 | DT_OMIT_NO_REF subnode
561 {
562 $$ = omit_node_if_unused($2);
563 }
David Gibson05898c62010-02-24 18:22:17 +1100564 | DT_LABEL subnode
Jon Loeliger30807ca2007-10-18 09:42:16 -0500565 {
David Gibson05898c62010-02-24 18:22:17 +1100566 add_label(&$2->labels, $1);
567 $$ = $2;
Jon Loeliger56412892007-10-23 09:28:54 -0500568 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000569 ;
570
571%%
572
David Gibsonc8544342014-01-03 23:23:23 +1100573void yyerror(char const *s)
574{
David Gibsonfa3f3f02014-01-03 23:57:39 +1100575 ERROR(&yylloc, "%s", s);
John Bonesioc0fa2e62010-10-20 14:44:58 -0700576}