2 * fmd_parser.y, parser generator for flashmap descriptor language
4 * Copyright (C) 2015 Google, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
21 #include "fmd_scanner.h"
26 struct flashmap_descriptor
*res
= NULL
;
32 struct unsigned_option maybe_intval
;
33 struct flashmap_descriptor
*region_ptr
;
34 struct descriptor_list region_listhdr
;
43 struct descriptor_node
{
44 struct flashmap_descriptor
*val
;
45 struct descriptor_node
*next
;
48 struct descriptor_list
{
50 struct descriptor_node
*head
;
51 struct descriptor_node
*tail
;
54 extern
struct flashmap_descriptor
*res
;
56 struct flashmap_descriptor
*parse_descriptor
(char *name
,
57 struct unsigned_option offset
, struct unsigned_option size
,
58 struct descriptor_list children
);
59 void yyerror(const char *s
);
62 %token
<intval
> INTEGER
64 %token
<strval
> STRING
66 %type
<region_ptr
> flash_region
67 %type
<strval
> region_name
68 %type
<strval
> region_annotation_opt
69 %type
<strval
> region_annotation
70 %type
<maybe_intval
> region_offset_opt
71 %type
<maybe_intval
> region_offset
72 %type
<maybe_intval
> region_size_opt
73 %type
<maybe_intval
> region_size
74 %type
<region_listhdr
> region_list_opt
75 %type
<region_listhdr
> region_list
76 %type
<region_listhdr
> region_list_entries
80 flash_chip: region_name region_offset_opt region_size region_list
82 if
(!(res
= parse_descriptor
($1, $2, $3, $4)))
85 flash_region: region_name region_annotation_opt region_offset_opt
86 region_size_opt region_list_opt
88 struct flashmap_descriptor
*node
= parse_descriptor
($1, $3, $4, $5);
92 char *annotation
= $2;
93 if
(annotation
&& !fmd_process_annotation_impl
(node
, annotation
)) {
94 ERROR
("Section '%s' has unexpected annotation '(%s)'\n",
95 node
->name
, annotation
);
105 perror
("E: While allocating section name");
109 region_annotation_opt: { $$
= NULL
; }
111 region_annotation: '(' STRING
')' { $$
= $2; };
112 region_offset_opt: { $$
= (struct unsigned_option
){false
, 0}; }
114 region_offset: '@' INTEGER
{ $$
= (struct unsigned_option
){true
, $2}; };
115 region_size_opt: { $$
= (struct unsigned_option
){false
, 0}; }
117 region_size: INTEGER
{ $$
= (struct unsigned_option
){true
, $1}; };
120 $$
= (struct descriptor_list
)
121 {.len
= 0, .head
= NULL
, .tail
= NULL
};
124 region_list: '{' region_list_entries
'}' { $$
= $2; };
125 region_list_entries: flash_region
127 struct descriptor_node
*node
= malloc
(sizeof
(*node
));
129 perror
("E: While allocating linked list node");
134 $$
= (struct descriptor_list
){.len
= 1, .head
= node
, .tail
= node
};
136 | region_list_entries flash_region
138 struct descriptor_node
*node
= malloc
(sizeof
(*node
));
140 perror
("E: While allocating linked list node");
146 $1.tail
->next
= node
;
147 $$
= (struct descriptor_list
)
148 {.len
= $1.len
+ 1, .head
= $1.head
, .tail
= node
};
153 struct flashmap_descriptor
*parse_descriptor
(char *name
,
154 struct unsigned_option offset
, struct unsigned_option size
,
155 struct descriptor_list children
)
157 struct flashmap_descriptor
*region
= malloc
(sizeof
(*region
));
159 perror
("E: While allocating descriptor section");
163 region
->offset_known
= offset.val_known
;
164 region
->offset
= offset.val
;
165 region
->size_known
= size.val_known
;
166 region
->size
= size.val
;
167 region
->list_len
= children.len
;
168 if
(region
->list_len
) {
169 region
->list
= malloc
(region
->list_len
* sizeof
(*region
->list
));
171 perror
("E: While allocating node children array");
174 struct descriptor_node
*cur_node
= children.head
;
175 for
(unsigned idx
= 0; idx
< region
->list_len
; ++idx
) {
176 region
->list
[idx
] = cur_node
->val
;
178 struct descriptor_node
*next_node
= cur_node
->next
;
180 cur_node
= next_node
;
188 void yyerror(const char *s
)
190 fprintf
(stderr
, "%s\n", s
);