aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-05-16 01:08:45 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2011-05-16 01:17:20 +0300
commite559f3f36c99988ee80ac4ec01f80ea6578beebe (patch)
treee9cd0ab93dc2901fce901a062c7c1ee7442979e5 /src
parenta0826b4c7cd66c4862d9b61bb7e14d73fcba28f6 (diff)
downloadgrecs-e559f3f36c99988ee80ac4ec01f80ea6578beebe.tar.gz
grecs-e559f3f36c99988ee80ac4ec01f80ea6578beebe.tar.bz2
Implement BIND config parser.
* am/grecs.m4: New option: parser-bind. * src/.gitignore: Update. * src/Make.am [GRECS_COND_BIND_PARSER]: Set GRECS_PARSER_BIND and GRECS_EXTRA_BIND. (GRECS_SRC): Include GRECS_PARSER_BIND. (EXTRA_DIST): Include GRECS_EXTRA_BIND. * src/bind-gram.y: New file. * src/bind-lex.l: New file. * src/format.c (grecs_txtacc_format_value): New function. * src/grecs.h (grecs_bind_parser): New proto. * src/parser.c: Set grecs_current_locus. * src/tree.c (grecs_node_bind): Return immediately if node==NULL. * src/yytrans: Update.
Diffstat (limited to 'src')
-rw-r--r--src/.gitignore4
-rw-r--r--src/Make.am13
-rw-r--r--src/bind-gram.y296
-rw-r--r--src/bind-lex.l224
-rw-r--r--src/format.c54
-rw-r--r--src/grecs.h10
-rw-r--r--src/meta1-gram.y1
-rw-r--r--src/parser.c2
-rw-r--r--src/preproc.c8
-rw-r--r--src/tree.c4
-rw-r--r--src/yytrans5
11 files changed, 612 insertions, 9 deletions
diff --git a/src/.gitignore b/src/.gitignore
index feb5040..0f52326 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -6,6 +6,10 @@ meta1-gram.c
6meta1-gram.h 6meta1-gram.h
7meta1-gram.output 7meta1-gram.output
8meta1-lex.c 8meta1-lex.c
9bind-gram.c
10bind-gram.h
11bind-gram.output
12bind-lex.c
9Make-inst.in 13Make-inst.in
10Make-shared.in 14Make-shared.in
11Make-static.in 15Make-static.in
diff --git a/src/Make.am b/src/Make.am
index 60c0f06..e05afc5 100644
--- a/src/Make.am
+++ b/src/Make.am
@@ -19,6 +19,11 @@ if GRECS_COND_META1_PARSER
19 GRECS_EXTRA_META1 = meta1-gram.h 19 GRECS_EXTRA_META1 = meta1-gram.h
20endif 20endif
21 21
22if GRECS_COND_BIND_PARSER
23 GRECS_PARSER_BIND = bind-gram.y bind-lex.l
24 GRECS_EXTRA_BIND = bind-gram.h
25endif
26
22GRECS_SRC = \ 27GRECS_SRC = \
23 asprintf.c\ 28 asprintf.c\
24 diag.c\ 29 diag.c\
@@ -39,11 +44,17 @@ GRECS_SRC = \
39 txtacc.c\ 44 txtacc.c\
40 version.c\ 45 version.c\
41 wordsplit.c\ 46 wordsplit.c\
47 $(GRECS_PARSER_BIND)\
42 $(GRECS_PARSER_META1) 48 $(GRECS_PARSER_META1)
43 49
44noinst_HEADERS = 50noinst_HEADERS =
45 51
46EXTRA_DIST=grecs-gram.h $(GRECS_EXTRA_META1) $(PP_SETUP_FILE) Make.am Make-inst.am Make-shared.am Make-static.am 52EXTRA_DIST=\
53 grecs-gram.h\
54 $(GRECS_EXTRA_BIND)\
55 $(GRECS_EXTRA_META1)\
56 $(PP_SETUP_FILE)\
57 Make.am Make-inst.am Make-shared.am Make-static.am
47 58
48INCLUDES = -I$(srcdir) -I$(top_srcdir)/@GRECS_SUBDIR@ @GRECS_INCLUDES@ @GRECS_HOST_PROJECT_INCLUDES@ 59INCLUDES = -I$(srcdir) -I$(top_srcdir)/@GRECS_SUBDIR@ @GRECS_INCLUDES@ @GRECS_HOST_PROJECT_INCLUDES@
49AM_YFLAGS = -dtv 60AM_YFLAGS = -dtv
diff --git a/src/bind-gram.y b/src/bind-gram.y
new file mode 100644
index 0000000..621070e
--- /dev/null
+++ b/src/bind-gram.y
@@ -0,0 +1,296 @@
1%{
2/* grecs - Gray's Extensible Configuration System
3 Copyright (C) 2007-2011 Sergey Poznyakoff
4
5 Grecs 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; either version 3 of the License, or (at your
8 option) any later version.
9
10 Grecs is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with Grecs. If not, see <http://www.gnu.org/licenses/>. */
17
18#ifdef HAVE_CONFIG_H
19# include <config.h>
20#endif
21#include <grecs.h>
22#include <grecs-gram.h>
23#include <stdlib.h>
24#include <stdarg.h>
25#include <string.h>
26#include <errno.h>
27
28int yylex(void);
29int yyerror(char *s);
30
31static struct grecs_node *parse_tree;
32extern int yy_flex_debug;
33extern int grecs_bind_new_source(const char *name);
34extern void grecs_bind_close_sources(void);
35
36static struct grecs_value *stmtlist_to_value(struct grecs_node *node);
37%}
38
39%union {
40 struct {
41 grecs_locus_t locus;
42 char *string;
43 } ident;
44 char *string;
45 grecs_value_t svalue, *pvalue;
46 struct grecs_list *list;
47 struct grecs_node *node;
48 grecs_locus_t locus;
49 struct { struct grecs_node *head, *tail; } node_list;
50}
51
52%token <ident> BIND_IDENT
53%token <string> BIND_STRING
54%type <string> string
55%type <svalue> value
56%type <pvalue> vallist tag
57%type <list> vlist
58%type <node> stmt simple block
59%type <node_list> stmtlist
60
61%%
62
63input : stmtlist
64 {
65 parse_tree = grecs_node_create(grecs_node_root,
66 &grecs_current_locus);
67 parse_tree->v.texttab = grecs_text_table();
68 grecs_node_bind(parse_tree, $1.head, 1);
69 }
70 ;
71
72stmtlist: stmt
73 {
74 $$.head = $$.tail = $1;
75 }
76 | stmtlist stmt
77 {
78 if ($2) {
79 if (!$1.head)
80 $1.head = $1.tail = $2;
81 else
82 grecs_node_bind($1.tail, $2, 0);
83 }
84 $$ = $1;
85 }
86 ;
87
88stmt : simple
89 | block
90 ;
91
92simple : BIND_IDENT vallist ';'
93 {
94 if (strcmp($1.string, "include") == 0 &&
95 $2->type == GRECS_TYPE_STRING) {
96 grecs_bind_new_source($2->v.string);
97 $$ = NULL;
98 } else {
99 $$ = grecs_node_create(grecs_node_stmt, &$1.locus);
100 $$->ident = $1.string;
101 $$->v.value = $2;
102 }
103 }
104 | string ';'
105 {
106 $$ = grecs_node_create(grecs_node_stmt,
107 &grecs_current_locus);
108 $$->ident = $1;
109 $$->v.value = NULL;
110 }
111 ;
112
113block : BIND_IDENT tag '{' stmtlist '}' opt_sc
114 {
115 $$ = grecs_node_create(grecs_node_block, &$1.locus);
116 $$->ident = $1.string;
117 $$->v.value = $2;
118 grecs_node_bind($$, $4.head, 1);
119 }
120 ;
121
122tag : /* empty */
123 {
124 $$ = NULL;
125 }
126 | BIND_IDENT
127 {
128 $$ = grecs_malloc(sizeof($$[0]));
129 $$->type = GRECS_TYPE_STRING;
130 $$->v.string = $1.string;
131 }
132 | BIND_STRING
133 {
134 $$ = grecs_malloc(sizeof($$[0]));
135 $$->type = GRECS_TYPE_STRING;
136 $$->v.string = $1;
137 }
138 ;
139
140vallist : vlist
141 {
142 size_t n;
143
144 if ((n = grecs_list_size($1)) == 1) {
145 $$ = grecs_list_index($1, 0);
146 } else {
147 size_t i;
148 struct grecs_list_entry *ep;
149
150 $$ = grecs_malloc(sizeof($$[0]));
151 $$->type = GRECS_TYPE_ARRAY;
152 $$->v.arg.c = n;
153 $$->v.arg.v = grecs_calloc(n,
154 sizeof($$->v.arg.v[0]));
155 for (i = 0, ep = $1->head; ep; i++, ep = ep->next)
156 $$->v.arg.v[i] = ep->data;
157 }
158 $1->free_entry = NULL;
159 grecs_list_free($1);
160 }
161 ;
162
163vlist : value
164 {
165 $$ = grecs_value_list_create();
166 grecs_list_append($$, grecs_value_ptr_from_static(&$1));
167 }
168 | vlist value
169 {
170 grecs_list_append($1, grecs_value_ptr_from_static(&$2));
171 }
172 | vlist BIND_IDENT '{' stmtlist '}'