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.
17 #include "fmd_scanner.h"
22 struct flashmap_descriptor
*res
= NULL
;
28 struct unsigned_option maybe_intval
;
29 struct flashmap_descriptor
*region_ptr
;
30 struct descriptor_list region_listhdr
;
39 struct descriptor_node
{
40 struct flashmap_descriptor
*val
;
41 struct descriptor_node
*next
;
44 struct descriptor_list
{
46 struct descriptor_node
*head
;
47 struct descriptor_node
*tail
;
50 extern
struct flashmap_descriptor
*res
;
52 struct flashmap_descriptor
*parse_descriptor
(char *name
,
53 struct unsigned_option offset
, struct unsigned_option size
,
54 struct descriptor_list children
);
55 void yyerror(const char *s
);
58 %token
<intval
> INTEGER
60 %token
<strval
> STRING
62 %type
<region_ptr
> flash_region
63 %type
<strval
> region_name
64 %type
<strval
> region_annotation_opt
65 %type
<strval
> region_annotation
66 %type
<maybe_intval
> region_offset_opt
67 %type
<maybe_intval
> region_offset
68 %type
<maybe_intval
> region_size_opt
69 %type
<maybe_intval
> region_size
70 %type
<region_listhdr
> region_list_opt
71 %type
<region_listhdr
> region_list
72 %type
<region_listhdr
> region_list_entries
76 flash_chip: region_name region_offset_opt region_size region_list
78 if
(!(res
= parse_descriptor
($1, $2, $3, $4)))
81 flash_region: region_name region_annotation_opt region_offset_opt
82 region_size_opt region_list_opt
84 struct flashmap_descriptor
*node
= parse_descriptor
($1, $3, $4, $5);
88 char *annotation
= $2;
89 if
(annotation
&& !fmd_process_annotation_impl
(node
, annotation
)) {
90 ERROR
("Section '%s' has unexpected annotation '(%s)'\n",
91 node
->name
, annotation
);
101 perror
("E: While allocating section name");
105 region_annotation_opt: { $$
= NULL
; }
107 region_annotation: '(' STRING
')' { $$
= $2; };
108 region_offset_opt: { $$
= (struct unsigned_option
){false
, 0}; }
110 region_offset: '@' INTEGER
{ $$
= (struct unsigned_option
){true
, $2}; };
111 region_size_opt: { $$
= (struct unsigned_option
){false
, 0}; }
113 region_size: INTEGER
{ $$
= (struct unsigned_option
){true
, $1}; };
116 $$
= (struct descriptor_list
)
117 {.len
= 0, .head
= NULL
, .tail
= NULL
};
120 region_list: '{' region_list_entries
'}' { $$
= $2; };
121 region_list_entries: flash_region
123 struct descriptor_node
*node
= malloc
(sizeof
(*node
));
125 perror
("E: While allocating linked list node");
130 $$
= (struct descriptor_list
){.len
= 1, .head
= node
, .tail
= node
};
132 | region_list_entries flash_region
134 struct descriptor_node
*node
= malloc
(sizeof
(*node
));
136 perror
("E: While allocating linked list node");
142 $1.tail
->next
= node
;
143 $$
= (struct descriptor_list
)
144 {.len
= $1.len
+ 1, .head
= $1.head
, .tail
= node
};
149 struct flashmap_descriptor
*parse_descriptor
(char *name
,
150 struct unsigned_option offset
, struct unsigned_option size
,
151 struct descriptor_list children
)
153 struct flashmap_descriptor
*region
= malloc
(sizeof
(*region
));
155 perror
("E: While allocating descriptor section");
159 region
->offset_known
= offset.val_known
;
160 region
->offset
= offset.val
;
161 region
->size_known
= size.val_known
;
162 region
->size
= size.val
;
163 region
->list_len
= children.len
;
164 if
(region
->list_len
) {
165 region
->list
= malloc
(region
->list_len
* sizeof
(*region
->list
));
167 perror
("E: While allocating node children array");
170 struct descriptor_node
*cur_node
= children.head
;
171 for
(unsigned idx
= 0; idx
< region
->list_len
; ++idx
) {
172 region
->list
[idx
] = cur_node
->val
;
174 struct descriptor_node
*next_node
= cur_node
->next
;
176 cur_node
= next_node
;
184 void yyerror(const char *s
)
186 fprintf
(stderr
, "%s\n", s
);