aboutsummaryrefslogtreecommitdiffstats
path: root/lib/grammar.y
diff options
context:
space:
mode:
authorJonathan McCrohan <jmccrohan@gmail.com>2011-12-01 22:56:23 +0000
committerJonathan McCrohan <jmccrohan@gmail.com>2011-12-01 22:56:23 +0000
commit429e46051dba814e7d6c74368eb1bba550222cbe (patch)
treeed1dd43cd23c69f156aae2165006a16a66262cef /lib/grammar.y
parent58bf1382be0cbcf3f9649286fd2719b789a1595f (diff)
downloadlibconfig-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);
}
}
;