diff options
author | Jonathan McCrohan <jmccrohan@gmail.com> | 2011-12-01 22:56:23 +0000 |
---|---|---|
committer | Jonathan McCrohan <jmccrohan@gmail.com> | 2011-12-01 22:56:23 +0000 |
commit | 429e46051dba814e7d6c74368eb1bba550222cbe (patch) | |
tree | ed1dd43cd23c69f156aae2165006a16a66262cef /grammar.y | |
parent | 58bf1382be0cbcf3f9649286fd2719b789a1595f (diff) | |
download | libconfig-429e46051dba814e7d6c74368eb1bba550222cbe.tar.gz |
Imported Upstream version 1.4.8upstream/1.4.8
Diffstat (limited to '')
-rw-r--r-- | lib/grammar.y (renamed from grammar.y) | 93 |
1 files changed, 58 insertions, 35 deletions
diff --git a/grammar.y b/lib/grammar.y index e484530..f578897 100644 --- a/grammar.y +++ b/lib/grammar.y @@ -1,20 +1,20 @@ /* -*- mode: C -*- */ /* ---------------------------------------------------------------------------- libconfig - A library for processing structured configuration files - Copyright (C) 2005-2008 Mark A Lindner - + Copyright (C) 2005-2010 Mark A Lindner + This file is part of libconfig. - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. - + This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - + You should have received a copy of the GNU Library General Public License along with this library; if not, see <http://www.gnu.org/licenses/>. @@ -27,6 +27,7 @@ %lex-param{void *scanner} %parse-param{void *scanner} %parse-param{struct parse_context *ctx} +%parse-param{struct scan_context *scan_ctx} %{ #include <string.h> @@ -39,30 +40,41 @@ #ifndef _STDLIB_H #define _STDLIB_H #endif - + #include <malloc.h> #endif -#include "private.h" +#include "parsectx.h" +#include "scanctx.h" /* these delcarations are provided to suppress compiler warnings */ extern int libconfig_yylex(); extern int libconfig_yyget_lineno(); - + static const char *err_array_elem_type = "mismatched element type in array"; static const char *err_duplicate_setting = "duplicate setting name"; +#define _delete(P) free((void *)(P)) + #define IN_ARRAY() \ (ctx->parent && (ctx->parent->type == CONFIG_TYPE_ARRAY)) #define IN_LIST() \ (ctx->parent && (ctx->parent->type == CONFIG_TYPE_LIST)) -#define CAPTURE_PARSE_POS(S) \ - (S)->line = (unsigned int)libconfig_yyget_lineno(scanner) +static void capture_parse_pos(void *scanner, struct scan_context *scan_ctx, + config_setting_t *setting) +{ + setting->line = (unsigned int)libconfig_yyget_lineno(scanner); + setting->file = scanctx_current_filename(scan_ctx); +} + +#define CAPTURE_PARSE_POS(S) \ + capture_parse_pos(scanner, scan_ctx, (S)) void libconfig_yyerror(void *scanner, struct parse_context *ctx, - char const *s) + struct scan_context *scan_ctx, char const *s) { + if(ctx->config->error_text) return; ctx->config->error_line = libconfig_yyget_lineno(scanner); ctx->config->error_text = s; } @@ -71,7 +83,7 @@ void libconfig_yyerror(void *scanner, struct parse_context *ctx, %union { - long ival; + int ival; long long llval; double fval; char *sval; @@ -81,7 +93,7 @@ void libconfig_yyerror(void *scanner, struct parse_context *ctx, %token <llval> TOK_INTEGER64 TOK_HEX64 %token <fval> TOK_FLOAT %token <sval> TOK_STRING TOK_NAME -%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 +%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_SEMICOLON TOK_GARBAGE TOK_ERROR %% @@ -100,15 +112,20 @@ setting_list_optional: | setting_list ; +setting_terminator: + /* empty */ + | TOK_SEMICOLON + | TOK_COMMA + ; + setting: TOK_NAME { ctx->setting = config_setting_add(ctx->parent, $1, CONFIG_TYPE_NONE); - free($1); - + if(ctx->setting == NULL) { - libconfig_yyerror(scanner, ctx, err_duplicate_setting); + libconfig_yyerror(scanner, ctx, scan_ctx, err_duplicate_setting); YYABORT; } else @@ -117,9 +134,9 @@ setting: } } - TOK_EQUALS value TOK_END + TOK_EQUALS value setting_terminator ; - + array: TOK_ARRAY_START { @@ -139,7 +156,7 @@ array: TOK_ARRAY_END { if(ctx->parent) - ctx->parent = ctx->parent->parent; + ctx->parent = ctx->parent->parent; } ; @@ -162,7 +179,7 @@ list: TOK_LIST_END { if(ctx->parent) - ctx->parent = ctx->parent->parent; + ctx->parent = ctx->parent->parent; } ; @@ -173,6 +190,11 @@ value: | group ; +string: + TOK_STRING { parsectx_append_string(ctx, $1); free($1); } + | string TOK_STRING { parsectx_append_string(ctx, $2); free($2); } + ; + simple_value: TOK_BOOLEAN { @@ -180,10 +202,10 @@ simple_value: { config_setting_t *e = config_setting_set_bool_elem(ctx->parent, -1, (int)$1); - + if(! e) { - libconfig_yyerror(scanner, ctx, err_array_elem_type); + libconfig_yyerror(scanner, ctx, scan_ctx, err_array_elem_type); YYABORT; } else @@ -201,7 +223,7 @@ simple_value: config_setting_t *e = config_setting_set_int_elem(ctx->parent, -1, $1); if(! e) { - libconfig_yyerror(scanner, ctx, err_array_elem_type); + libconfig_yyerror(scanner, ctx, scan_ctx, err_array_elem_type); YYABORT; } else @@ -223,7 +245,7 @@ simple_value: config_setting_t *e = config_setting_set_int64_elem(ctx->parent, -1, $1); if(! e) { - libconfig_yyerror(scanner, ctx, err_array_elem_type); + libconfig_yyerror(scanner, ctx, scan_ctx, err_array_elem_type); YYABORT; } else @@ -245,7 +267,7 @@ simple_value: config_setting_t *e = config_setting_set_int_elem(ctx->parent, -1, $1); if(! e) { - libconfig_yyerror(scanner, ctx, err_array_elem_type); + libconfig_yyerror(scanner, ctx, scan_ctx, err_array_elem_type); YYABORT; } else @@ -267,7 +289,7 @@ simple_value: config_setting_t *e = config_setting_set_int64_elem(ctx->parent, -1, $1); if(! e) { - libconfig_yyerror(scanner, ctx, err_array_elem_type); + libconfig_yyerror(scanner, ctx, scan_ctx, err_array_elem_type); YYABORT; } else @@ -289,7 +311,7 @@ simple_value: config_setting_t *e = config_setting_set_float_elem(ctx->parent, -1, $1); if(! e) { - libconfig_yyerror(scanner, ctx, err_array_elem_type); + libconfig_yyerror(scanner, ctx, scan_ctx, err_array_elem_type); YYABORT; } else @@ -300,17 +322,17 @@ simple_value: else config_setting_set_float(ctx->setting, $1); } - | TOK_STRING + | string { if(IN_ARRAY() || IN_LIST()) { - config_setting_t *e = config_setting_set_string_elem(ctx->parent, -1, - $1); - free($1); - + const char *s = parsectx_take_string(ctx); + config_setting_t *e = config_setting_set_string_elem(ctx->parent, -1, s); + _delete(s); + if(! e) { - libconfig_yyerror(scanner, ctx, err_array_elem_type); + libconfig_yyerror(scanner, ctx, scan_ctx, err_array_elem_type); YYABORT; } else @@ -320,8 +342,9 @@ simple_value: } else { - config_setting_set_string(ctx->setting, $1); - free($1); + const char *s = parsectx_take_string(ctx); + config_setting_set_string(ctx->setting, s); + _delete(s); } } ; |