BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /**
2 * @file NCDConfigParser_parse.y
3 * @author Ambroz Bizjak <ambrop7@gmail.com>
4 *
5 * @section LICENSE
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29  
30 // argument for passing state to parser hooks
31 %extra_argument { struct parser_state *parser_out }
32  
33 // type of structure representing tokens
34 %token_type { struct token }
35  
36 // token destructor frees extra memory allocated for tokens
37 %token_destructor { free_token($$); }
38  
39 // types of nonterminals
40 %type list_contents { struct value }
41 %type list { struct value }
42 %type map_contents { struct value }
43 %type map { struct value }
44 %type value { struct value }
45  
46 // mention parser_out in some destructor to and avoid unused variable warning
47 %destructor list_contents { (void)parser_out; }
48  
49 // try to dynamically grow the parse stack
50 %stack_size 0
51  
52 // on syntax error, set the corresponding error flag
53 %syntax_error {
54 parser_out->error_flags |= ERROR_FLAG_SYNTAX;
55 }
56  
57 // workaroud Lemon bug: if the stack overflows, the token that caused the overflow will be leaked
58 %stack_overflow {
59 if (yypMinor) {
60 free_token(yypMinor->yy0);
61 }
62 }
63  
64 input ::= value(A). {
65 if (!A.have) {
66 goto failZ0;
67 }
68  
69 if (!NCDVal_IsInvalid(parser_out->value)) {
70 // should never happen
71 parser_out->error_flags |= ERROR_FLAG_SYNTAX;
72 goto failZ0;
73 }
74  
75 if (!NCDValCons_Complete(&parser_out->cons, A.v, &parser_out->value, &parser_out->cons_error)) {
76 handle_cons_error(parser_out);
77 goto failZ0;
78 }
79  
80 failZ0:;
81 }
82  
83 list_contents(R) ::= value(A). {
84 if (!A.have) {
85 goto failL0;
86 }
87  
88 NCDValCons_NewList(&parser_out->cons, &R.v);
89  
90 if (!NCDValCons_ListPrepend(&parser_out->cons, &R.v, A.v, &parser_out->cons_error)) {
91 handle_cons_error(parser_out);
92 goto failL0;
93 }
94  
95 R.have = 1;
96 goto doneL;
97  
98 failL0:
99 R.have = 0;
100 doneL:;
101 }
102  
103 list_contents(R) ::= value(A) COMMA list_contents(N). {
104 if (!A.have || !N.have) {
105 goto failM0;
106 }
107  
108 if (!NCDValCons_ListPrepend(&parser_out->cons, &N.v, A.v, &parser_out->cons_error)) {
109 handle_cons_error(parser_out);
110 goto failM0;
111 }
112  
113 R.have = 1;
114 R.v = N.v;
115 goto doneM;
116  
117 failM0:
118 R.have = 0;
119 doneM:;
120 }
121  
122 list(R) ::= CURLY_OPEN CURLY_CLOSE. {
123 NCDValCons_NewList(&parser_out->cons, &R.v);
124 R.have = 1;
125 }
126  
127 list(R) ::= CURLY_OPEN list_contents(A) CURLY_CLOSE. {
128 R = A;
129 }
130  
131 map_contents(R) ::= value(A) COLON value(B). {
132 if (!A.have || !B.have) {
133 goto failS0;
134 }
135  
136 NCDValCons_NewMap(&parser_out->cons, &R.v);
137  
138 if (!NCDValCons_MapInsert(&parser_out->cons, &R.v, A.v, B.v, &parser_out->cons_error)) {
139 handle_cons_error(parser_out);
140 goto failS0;
141 }
142  
143 R.have = 1;
144 goto doneS;
145  
146 failS0:
147 R.have = 0;
148 doneS:;
149 }
150  
151 map_contents(R) ::= value(A) COLON value(B) COMMA map_contents(N). {
152 if (!A.have || !B.have || !N.have) {
153 goto failT0;
154 }
155  
156 if (!NCDValCons_MapInsert(&parser_out->cons, &N.v, A.v, B.v, &parser_out->cons_error)) {
157 handle_cons_error(parser_out);
158 goto failT0;
159 }
160  
161 R.have = 1;
162 R.v = N.v;
163 goto doneT;
164  
165 failT0:
166 R.have = 0;
167 doneT:;
168 }
169  
170 map(R) ::= BRACKET_OPEN BRACKET_CLOSE. {
171 NCDValCons_NewMap(&parser_out->cons, &R.v);
172 R.have = 1;
173 }
174  
175 map(R) ::= BRACKET_OPEN map_contents(A) BRACKET_CLOSE. {
176 R = A;
177 }
178  
179 value(R) ::= STRING(A). {
180 ASSERT(A.str)
181  
182 if (!NCDValCons_NewString(&parser_out->cons, (const uint8_t *)A.str, A.len, &R.v, &parser_out->cons_error)) {
183 handle_cons_error(parser_out);
184 goto failU0;
185 }
186  
187 R.have = 1;
188 goto doneU;
189  
190 failU0:
191 R.have = 0;
192 doneU:;
193 free_token(A);
194 }
195  
196 value(R) ::= list(A). {
197 R = A;
198 }
199  
200 value(R) ::= map(A). {
201 R = A;
202 }