2 * oconfig - src/parser.y
3 * Copyright (C) 2007,2008 Florian octo Forster <octo at verplant.org>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; only version 2 of the License is applicable.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "aux_types.h"
25 static char *unquote (const char *orig);
26 static int yyerror (const char *s);
31 extern int yylex (void);
33 extern oconfig_item_t *ci_root;
49 %token <number> NUMBER
50 %token <boolean> BTRUE BFALSE
51 %token <string> QUOTED_STRING UNQUOTED_STRING
52 %token SLASH OPENBRAC CLOSEBRAC EOL
55 %type <string> identifier
58 %type <al> argument_list
60 %type <ci> block_begin
62 %type <string> block_end
66 %type <sl> statement_list
67 %type <ci> entire_file
69 /* pass an verbose, specific error message to yyerror() */
74 QUOTED_STRING {$$ = unquote ($1);}
75 | UNQUOTED_STRING {$$ = strdup ($1);}
79 NUMBER {$$.value.number = $1; $$.type = OCONFIG_TYPE_NUMBER;}
80 | BTRUE {$$.value.boolean = 1; $$.type = OCONFIG_TYPE_BOOLEAN;}
81 | BFALSE {$$.value.boolean = 0; $$.type = OCONFIG_TYPE_BOOLEAN;}
82 | string {$$.value.string = $1; $$.type = OCONFIG_TYPE_STRING;}
86 argument_list argument
90 $$.argument = realloc ($$.argument, $$.argument_num * sizeof (oconfig_value_t));
91 $$.argument[$$.argument_num-1] = $2;
95 $$.argument = malloc (sizeof (oconfig_value_t));
102 UNQUOTED_STRING {$$ = strdup ($1);}
106 identifier argument_list EOL
108 memset (&$$, '\0', sizeof ($$));
110 $$.values = $2.argument;
111 $$.values_num = $2.argument_num;
116 OPENBRAC identifier CLOSEBRAC EOL
118 memset (&$$, '\0', sizeof ($$));
122 OPENBRAC identifier argument_list CLOSEBRAC EOL
124 memset (&$$, '\0', sizeof ($$));
126 $$.values = $3.argument;
127 $$.values_num = $3.argument_num;
132 OPENBRAC SLASH identifier CLOSEBRAC EOL
139 block_begin statement_list block_end
141 if (strcmp ($1.key, $3) != 0)
143 printf ("block_begin = %s; block_end = %s;\n", $1.key, $3);
144 yyerror ("Block not closed..\n");
147 free ($3); $3 = NULL;
149 $$.children = $2.statement;
150 $$.children_num = $2.statement_num;
152 | block_begin block_end
154 if (strcmp ($1.key, $2) != 0)
156 printf ("block_begin = %s; block_end = %s;\n", $1.key, $2);
157 yyerror ("Block not closed..\n");
160 free ($2); $2 = NULL;
170 | EOL {$$.values_num = 0;}
174 statement_list statement
177 if (($2.values_num > 0) || ($2.children_num > 0))
180 $$.statement = realloc ($$.statement, $$.statement_num * sizeof (oconfig_item_t));
181 $$.statement[$$.statement_num-1] = $2;
186 if (($1.values_num > 0) || ($1.children_num > 0))
188 $$.statement = malloc (sizeof (oconfig_item_t));
189 $$.statement[0] = $1;
190 $$.statement_num = 1;
195 $$.statement_num = 0;
203 ci_root = malloc (sizeof (oconfig_item_t));
204 memset (ci_root, '\0', sizeof (oconfig_item_t));
205 ci_root->children = $1.statement;
206 ci_root->children_num = $1.statement_num;
210 ci_root = malloc (sizeof (oconfig_item_t));
211 memset (ci_root, '\0', sizeof (oconfig_item_t));
212 ci_root->children = NULL;
213 ci_root->children_num = 0;
218 static int yyerror (const char *s)
227 fprintf (stderr, "Parse error in file `%s', line %i near `%s': %s\n",
228 c_file, yylineno, text, s);
232 static char *unquote (const char *orig)
234 char *ret = strdup (orig);
243 if ((len < 2) || (ret[0] != '"') || (ret[len - 1] != '"'))
247 memmove (ret, ret + 1, len);
250 for (i = 0; i < len; i++)
254 memmove (ret + i, ret + (i + 1), len - i);
260 } /* char *unquote */