Fixed license declaration at spec file
[platform/upstream/gdbm.git] / src / gram.y
1 %{
2 /* This file is part of GDBM, the GNU data base manager.
3    Copyright (C) 1990, 1991, 1993, 2007, 2011, 2013 Free Software Foundation,
4    Inc.
5
6    GDBM 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; either version 3, or (at your option)
9    any later version.
10
11    GDBM is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with GDBM. If not, see <http://www.gnu.org/licenses/>.    */
18
19 #include <autoconf.h>
20 #include "gdbmtool.h"
21
22 struct dsegm *dsdef[DS_MAX];
23   
24 %}
25
26 %error-verbose
27 %locations
28      
29 %token <type> T_TYPE
30 %token T_OFF "off"
31        T_PAD "pad"
32        T_DEF "define"
33        T_SET "set"
34        T_UNSET "unset"
35        T_BOGUS
36
37 %token <cmd> T_CMD "command verb"
38 %token <num> T_NUM "number"
39 %token <string> T_IDENT "identifier" T_WORD "word"
40 %type <string> string 
41 %type <arg> arg
42 %type <arglist> arglist arg1list
43 %type <dsegm> def defbody
44 %type <dsegmlist> deflist
45 %type <num> defid
46 %type <kvpair> kvpair compound value
47 %type <kvlist> kvlist
48 %type <slist> slist
49
50 %union {
51   char *string;
52   struct kvpair *kvpair;
53   struct { struct kvpair *head, *tail; } kvlist;
54   struct { struct slist *head, *tail; } slist;
55   struct gdbmarg *arg;
56   struct gdbmarglist arglist;
57   int num;
58   struct datadef *type;
59   struct dsegm *dsegm;
60   struct { struct dsegm *head, *tail; } dsegmlist;
61   struct command *cmd;
62 }
63
64 %%
65
66 input     : /* empty */
67           | stmtlist
68           ;
69
70 stmtlist  : stmt
71           | stmtlist stmt
72           ;
73
74 stmt      : /* empty */ '\n'
75           | T_CMD arglist '\n'
76             {
77               if (run_command ($1, &$2) && !interactive)
78                 exit (EXIT_USAGE);
79               gdbmarglist_free (&$2);
80             }
81           | set '\n'
82           | defn '\n'
83           | T_BOGUS '\n'
84             {
85               if (interactive)
86                 {
87                   yyclearin;
88                   yyerrok;
89                 }
90               else
91                 YYERROR;
92             }
93           | error { end_def(); } '\n'
94             {
95               if (interactive)
96                 {
97                   yyclearin;
98                   yyerrok;
99                 }
100               else
101                 YYERROR;
102             }
103           ;
104
105 arglist   : /* empty */
106             {
107               gdbmarglist_init (&$$, NULL);
108             }
109           | arg1list
110           ;
111
112 arg1list  : arg
113             {
114               gdbmarglist_init (&$$, $1);
115             }
116           | arg1list arg
117             {
118               gdbmarglist_add (&$1, $2);
119               $$ = $1;
120             }
121           ;
122
123 arg       : string
124             {
125               $$ = gdbmarg_string ($1, &@1);
126             }
127           | compound
128             {
129               $$ = gdbmarg_kvpair ($1, &@1);
130             }
131           ;
132
133 compound  : '{' kvlist '}'
134             {
135               $$ = $2.head;
136             }
137           ;
138
139 kvlist    : kvpair
140             {
141               $$.head = $$.tail = $1;
142             }
143           | kvlist ',' kvpair
144             {
145               $1.tail->next = $3;
146               $1.tail = $3;
147               $$ = $1;
148             }
149           ;
150
151 kvpair    : value
152           | T_IDENT '=' value
153             {
154               $3->key = $1;
155               $$ = $3;
156             }
157           ;
158
159 value     : string
160             {
161               $$ = kvpair_string (&@1, $1);
162             }
163           | '{' slist '}'
164             {
165               $$ = kvpair_list (&@1, $2.head);
166             }
167           ;
168
169 slist     : string
170             {
171               $$.head = $$.tail = slist_new ($1);
172             }
173           | slist ',' string
174             {
175               struct slist *s = slist_new ($3);
176               $1.tail->next = s;
177               $1.tail = s;
178               $$ = $1;
179             }
180           ;
181
182 string    : T_IDENT
183           | T_WORD
184           ;
185
186 defn      : T_DEF defid { begin_def (); } defbody
187             {
188               end_def ();
189               dsegm_free_list (dsdef[$2]);
190               dsdef[$2] = $4;
191             }
192           ;
193
194 defbody   : '{' deflist optcomma '}'
195             {
196               $$ = $2.head;
197             }
198           | T_TYPE
199             {
200               $$ = dsegm_new_field ($1, NULL, 1);
201             }
202           ;
203
204 optcomma  : /* empty */
205           | ','
206           ;
207
208 defid     : T_IDENT
209             {
210               if (strcmp ($1, "key") == 0)
211                 $$ = DS_KEY;
212               else if (strcmp ($1, "content") == 0)
213                 $$ = DS_CONTENT;
214               else
215                 {
216                   terror (_("expected \"key\" or \"content\", "
217                             "but found \"%s\""), $1);
218                   YYERROR;
219                 }
220             }
221           ;
222
223 deflist   : def
224             {
225               $$.head = $$.tail = $1;
226             }
227           | deflist ',' def
228             {
229               $1.tail->next = $3;
230               $1.tail = $3;
231               $$ = $1;
232             }
233           ;
234
235 def       : T_TYPE T_IDENT
236             {
237               $$ = dsegm_new_field ($1, $2, 1);
238             }
239           | T_TYPE T_IDENT '[' T_NUM ']'
240             {
241               $$ = dsegm_new_field ($1, $2, $4);
242             }
243           | T_OFF T_NUM
244             {
245               $$ = dsegm_new (FDEF_OFF);
246               $$->v.n = $2;
247             }
248           | T_PAD T_NUM
249             {
250               $$ = dsegm_new (FDEF_PAD);
251               $$->v.n = $2;
252             }
253           ;
254
255 set       : T_SET
256             {
257               variable_print_all (stdout);
258             }
259           | T_SET asgnlist
260           | T_UNSET varlist
261           ;
262
263 asgnlist  : asgn
264           | asgnlist asgn
265           ;
266
267 asgn      : T_IDENT
268             {
269               int t = 1;
270               int rc;
271               char *varname = $1;
272               
273               rc = variable_set (varname, VART_BOOL, &t);
274               if (rc == VAR_ERR_NOTDEF && strncmp (varname, "no", 2) == 0)
275                 {
276                   t = 0;
277                   varname += 2;
278                   rc = variable_set (varname, VART_BOOL, &t);
279                 }
280
281               switch (rc)
282                 {
283                 case VAR_OK:
284                   break;
285                   
286                 case VAR_ERR_NOTDEF:
287                   lerror (&@1, _("no such variable: %s"), varname);
288                   break;
289
290                 case VAR_ERR_BADTYPE:
291                   lerror (&@1, _("%s is not a boolean variable"), varname);
292                   break;
293
294                 default:
295                   lerror (&@1, _("unexpected error setting %s: %d"), $1, rc);
296                 }
297               free($1);
298             }
299           | T_IDENT '=' string
300             {
301               int rc = variable_set ($1, VART_STRING, $3);
302               switch (rc)
303                 {
304                 case VAR_OK:
305                   break;
306                   
307                 case VAR_ERR_NOTDEF:
308                   lerror (&@1, _("no such variable: %s"), $1);
309                   break;
310
311                 case VAR_ERR_BADTYPE:
312                   lerror (&@1, _("%s: bad variable type"), $1);
313                   break;
314
315                 case VAR_ERR_BADVALUE:
316                   lerror (&@1, _("%s: value %s is not allowed"), $1, $3);
317                   break;
318
319                 default:
320                   lerror (&@1, _("unexpected error setting %s: %d"), $1, rc);
321                 }
322               free ($1);
323               free ($3);
324             }
325           ;
326
327 varlist   : var
328           | varlist var
329           ;
330
331 var       : T_IDENT
332             {
333               int rc = variable_unset ($1);
334               switch (rc)
335                 {
336                 case VAR_OK:
337                   break;
338                   
339                 case VAR_ERR_NOTDEF:
340                   lerror (&@1, _("no such variable: %s"), $1);
341                   break;
342
343                 case VAR_ERR_BADVALUE:
344                   lerror (&@1, _("%s: variable cannot be unset"), $1);
345                   break;
346                 }
347               free($1);
348             }
349           ;
350
351 %%
352
353 void
354 terror (const char *fmt, ...)
355 {
356   va_list ap;
357
358   va_start (ap, fmt);
359   vlerror (&yylloc, fmt, ap);
360   va_end (ap);
361 }
362
363 int
364 yyerror (char *s)
365 {
366   terror ("%s", s);
367   return 0;
368 }