root/library/bdm/base/libconfig/grammar.y @ 390

Revision 248, 7.8 kB (checked in by smidl, 15 years ago)

doc

Line 
1/* -*- mode: C -*- */
2/* ----------------------------------------------------------------------------
3   libconfig - A library for processing structured configuration files
4   Copyright (C) 2005-2008  Mark A Lindner
5 
6   This file is part of libconfig.
7   
8   This library is free software; you can redistribute it and/or
9   modify it under the terms of the GNU Lesser General Public License
10   as published by the Free Software Foundation; either version 2.1 of
11   the License, or (at your option) any later version.
12   
13   This library is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16   Lesser General Public License for more details.
17   
18   You should have received a copy of the GNU Library General Public
19   License along with this library; if not, see
20   <http://www.gnu.org/licenses/>.
21   ----------------------------------------------------------------------------
22*/
23
24%defines
25%output="y.tab.c"
26%pure-parser
27%lex-param{void *scanner}
28%parse-param{void *scanner}
29%parse-param{struct parse_context *ctx}
30
31%{
32#include <string.h>
33#include <stdlib.h>
34#include "libconfig.h"
35#ifdef WIN32
36#include "wincompat.h"
37
38/* prevent warnings about redefined malloc/free in generated code: */
39#ifndef _STDLIB_H
40#define _STDLIB_H
41#endif
42 
43#include <malloc.h>
44#endif
45#include "private.h"
46
47/* these delcarations are provided to suppress compiler warnings */
48extern int libconfig_yylex();
49extern int libconfig_yyget_lineno();
50 
51static const char *err_array_elem_type = "mismatched element type in array";
52static const char *err_duplicate_setting = "duplicate setting name";
53
54#define IN_ARRAY() \
55  (ctx->parent && (ctx->parent->type == CONFIG_TYPE_ARRAY))
56
57#define IN_LIST() \
58  (ctx->parent && (ctx->parent->type == CONFIG_TYPE_LIST))
59
60#define CAPTURE_PARSE_POS(S)                                    \
61  (S)->line = (unsigned int)libconfig_yyget_lineno(scanner)
62
63void libconfig_yyerror(void *scanner, struct parse_context *ctx,
64                      char const *s)
65{
66  ctx->config->error_line = libconfig_yyget_lineno(scanner);
67  ctx->config->error_text = s;
68}
69
70%}
71
72%union
73{
74  long ival;
75  long long llval;
76  double fval;
77  char *sval;
78}
79
80%token <ival> TOK_BOOLEAN TOK_INTEGER TOK_HEX
81%token <llval> TOK_INTEGER64 TOK_HEX64
82%token <fval> TOK_FLOAT
83%token <sval> TOK_STRING TOK_NAME
84%token TOK_EQUALS TOK_NEWLINE TOK_ARRAY_START TOK_ARRAY_END TOK_LIST_START TOK_LIST_END TOK_COMMA TOK_GROUP_START TOK_GROUP_END TOK_END TOK_GARBAGE
85
86%%
87
88configuration:
89    /* empty */
90  | setting_list
91  ;
92
93setting_list:
94    setting
95  | setting_list setting
96  ;
97
98setting_list_optional:
99    /* empty */
100  | setting_list
101  ;
102
103setting:
104  TOK_NAME
105  {
106    ctx->setting = config_setting_add(ctx->parent, $1, CONFIG_TYPE_NONE);
107    free($1);
108 
109    if(ctx->setting == NULL)
110    {
111      libconfig_yyerror(scanner, ctx, err_duplicate_setting);
112      YYABORT;
113    }
114    else
115    {
116      CAPTURE_PARSE_POS(ctx->setting);
117    }
118  }
119
120  TOK_EQUALS value TOK_END
121  ;
122 
123array:
124  TOK_ARRAY_START
125  {
126    if(IN_LIST())
127    {
128      ctx->parent = config_setting_add(ctx->parent, NULL, CONFIG_TYPE_ARRAY);
129      CAPTURE_PARSE_POS(ctx->parent);
130    }
131    else
132    {
133      ctx->setting->type = CONFIG_TYPE_ARRAY;
134      ctx->parent = ctx->setting;
135      ctx->setting = NULL;
136    }
137  }
138  simple_value_list_optional
139  TOK_ARRAY_END
140  {
141    if(ctx->parent)
142      ctx->parent = ctx->parent->parent;   
143  }
144  ;
145
146list:
147  TOK_LIST_START
148  {
149    if(IN_LIST())
150    {
151      ctx->parent = config_setting_add(ctx->parent, NULL, CONFIG_TYPE_LIST);
152      CAPTURE_PARSE_POS(ctx->parent);
153    }
154    else
155    {
156      ctx->setting->type = CONFIG_TYPE_LIST;
157      ctx->parent = ctx->setting;
158      ctx->setting = NULL;
159    }
160  }
161  value_list_optional
162  TOK_LIST_END
163  {
164    if(ctx->parent)
165      ctx->parent = ctx->parent->parent;   
166  }
167  ;
168
169value:
170    simple_value
171  | array
172  | list
173  | group
174  ;
175
176simple_value:
177    TOK_BOOLEAN
178  {
179    if(IN_ARRAY() || IN_LIST())
180    {
181      config_setting_t *e = config_setting_set_bool_elem(ctx->parent, -1,
182                                                         (int)$1);
183     
184      if(! e)
185      {
186        libconfig_yyerror(scanner, ctx, err_array_elem_type);
187        YYABORT;
188      }
189      else
190      {
191        CAPTURE_PARSE_POS(e);
192      }
193    }
194    else
195      config_setting_set_bool(ctx->setting, (int)$1);
196  }
197  | TOK_INTEGER
198  {
199    if(IN_ARRAY() || IN_LIST())
200    {
201      config_setting_t *e = config_setting_set_int_elem(ctx->parent, -1, $1);
202      if(! e)
203      {
204        libconfig_yyerror(scanner, ctx, err_array_elem_type);
205        YYABORT;
206      }
207      else
208      {
209        config_setting_set_format(e, CONFIG_FORMAT_DEFAULT);
210        CAPTURE_PARSE_POS(e);
211      }
212    }
213    else
214    {
215      config_setting_set_int(ctx->setting, $1);
216      config_setting_set_format(ctx->setting, CONFIG_FORMAT_DEFAULT);
217    }
218  }
219  | TOK_INTEGER64
220  {
221    if(IN_ARRAY() || IN_LIST())
222    {
223      config_setting_t *e = config_setting_set_int64_elem(ctx->parent, -1, $1);
224      if(! e)
225      {
226        libconfig_yyerror(scanner, ctx, err_array_elem_type);
227        YYABORT;
228      }
229      else
230      {
231        config_setting_set_format(e, CONFIG_FORMAT_DEFAULT);
232        CAPTURE_PARSE_POS(e);
233      }
234    }
235    else
236    {
237      config_setting_set_int64(ctx->setting, $1);
238      config_setting_set_format(ctx->setting, CONFIG_FORMAT_DEFAULT);
239    }
240  }
241  | TOK_HEX
242  {
243    if(IN_ARRAY() || IN_LIST())
244    {
245      config_setting_t *e = config_setting_set_int_elem(ctx->parent, -1, $1);
246      if(! e)
247      {
248        libconfig_yyerror(scanner, ctx, err_array_elem_type);
249        YYABORT;
250      }
251      else
252      {
253        config_setting_set_format(e, CONFIG_FORMAT_HEX);
254        CAPTURE_PARSE_POS(e);
255      }
256    }
257    else
258    {
259      config_setting_set_int(ctx->setting, $1);
260      config_setting_set_format(ctx->setting, CONFIG_FORMAT_HEX);
261    }
262  }
263  | TOK_HEX64
264  {
265    if(IN_ARRAY() || IN_LIST())
266    {
267      config_setting_t *e = config_setting_set_int64_elem(ctx->parent, -1, $1);
268      if(! e)
269      {
270        libconfig_yyerror(scanner, ctx, err_array_elem_type);
271        YYABORT;
272      }
273      else
274      {
275        config_setting_set_format(e, CONFIG_FORMAT_HEX);
276        CAPTURE_PARSE_POS(e);
277      }
278    }
279    else
280    {
281      config_setting_set_int64(ctx->setting, $1);
282      config_setting_set_format(ctx->setting, CONFIG_FORMAT_HEX);
283    }
284  }
285  | TOK_FLOAT
286  {
287    if(IN_ARRAY() || IN_LIST())
288    {
289      config_setting_t *e = config_setting_set_float_elem(ctx->parent, -1, $1);
290      if(! e)
291      {
292        libconfig_yyerror(scanner, ctx, err_array_elem_type);
293        YYABORT;
294      }
295      else
296      {
297        CAPTURE_PARSE_POS(e);
298      }
299    }
300    else
301      config_setting_set_float(ctx->setting, $1);
302  }
303  | TOK_STRING
304  {
305    if(IN_ARRAY() || IN_LIST())
306    {
307      config_setting_t *e = config_setting_set_string_elem(ctx->parent, -1,
308                                                           $1);
309      free($1);
310     
311      if(! e)
312      {
313        libconfig_yyerror(scanner, ctx, err_array_elem_type);
314        YYABORT;
315      }
316      else
317      {
318        CAPTURE_PARSE_POS(e);
319      }
320    }
321    else
322    {
323      config_setting_set_string(ctx->setting, $1);
324      free($1);
325    }
326  }
327  ;
328
329value_list:
330    value
331  | value_list TOK_COMMA value
332  ;
333
334value_list_optional:
335    /* empty */
336  | value_list
337  ;
338
339simple_value_list:
340    simple_value
341  | simple_value_list TOK_COMMA simple_value
342  ;
343
344simple_value_list_optional:
345    /* empty */
346  | simple_value_list
347  ;
348
349group:
350  TOK_GROUP_START
351  {
352    if(IN_LIST())
353    {
354      ctx->parent = config_setting_add(ctx->parent, NULL, CONFIG_TYPE_GROUP);
355      CAPTURE_PARSE_POS(ctx->parent);
356    }
357    else
358    {
359      ctx->setting->type = CONFIG_TYPE_GROUP;
360      ctx->parent = ctx->setting;
361      ctx->setting = NULL;
362    }
363  }
364  setting_list_optional
365  TOK_GROUP_END
366  {
367    if(ctx->parent)
368      ctx->parent = ctx->parent->parent;
369  }
370  ;
371
372%%
Note: See TracBrowser for help on using the browser.