diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-16 01:08:45 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-16 01:17:20 +0300 |
commit | e559f3f36c99988ee80ac4ec01f80ea6578beebe (patch) | |
tree | e9cd0ab93dc2901fce901a062c7c1ee7442979e5 /src | |
parent | a0826b4c7cd66c4862d9b61bb7e14d73fcba28f6 (diff) | |
download | grecs-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/.gitignore | 4 | ||||
-rw-r--r-- | src/Make.am | 13 | ||||
-rw-r--r-- | src/bind-gram.y | 296 | ||||
-rw-r--r-- | src/bind-lex.l | 224 | ||||
-rw-r--r-- | src/format.c | 54 | ||||
-rw-r--r-- | src/grecs.h | 10 | ||||
-rw-r--r-- | src/meta1-gram.y | 1 | ||||
-rw-r--r-- | src/parser.c | 2 | ||||
-rw-r--r-- | src/preproc.c | 8 | ||||
-rw-r--r-- | src/tree.c | 4 | ||||
-rw-r--r-- | src/yytrans | 5 |
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 | |||
6 | meta1-gram.h | 6 | meta1-gram.h |
7 | meta1-gram.output | 7 | meta1-gram.output |
8 | meta1-lex.c | 8 | meta1-lex.c |
9 | bind-gram.c | ||
10 | bind-gram.h | ||
11 | bind-gram.output | ||
12 | bind-lex.c | ||
9 | Make-inst.in | 13 | Make-inst.in |
10 | Make-shared.in | 14 | Make-shared.in |
11 | Make-static.in | 15 | Make-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 |
20 | endif | 20 | endif |
21 | 21 | ||
22 | if GRECS_COND_BIND_PARSER | ||
23 | GRECS_PARSER_BIND = bind-gram.y bind-lex.l | ||
24 | GRECS_EXTRA_BIND = bind-gram.h | ||
25 | endif | ||
26 | |||
22 | GRECS_SRC = \ | 27 | GRECS_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 | ||
44 | noinst_HEADERS = | 50 | noinst_HEADERS = |
45 | 51 | ||
46 | EXTRA_DIST=grecs-gram.h $(GRECS_EXTRA_META1) $(PP_SETUP_FILE) Make.am Make-inst.am Make-shared.am Make-static.am | 52 | EXTRA_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 | ||
48 | INCLUDES = -I$(srcdir) -I$(top_srcdir)/@GRECS_SUBDIR@ @GRECS_INCLUDES@ @GRECS_HOST_PROJECT_INCLUDES@ | 59 | INCLUDES = -I$(srcdir) -I$(top_srcdir)/@GRECS_SUBDIR@ @GRECS_INCLUDES@ @GRECS_HOST_PROJECT_INCLUDES@ |
49 | AM_YFLAGS = -dtv | 60 | AM_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 | |||
28 | int yylex(void); | ||
29 | int yyerror(char *s); | ||
30 | |||
31 | static struct grecs_node *parse_tree; | ||
32 | extern int yy_flex_debug; | ||
33 | extern int grecs_bind_new_source(const char *name); | ||
34 | extern void grecs_bind_close_sources(void); | ||
35 | |||
36 | static 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 | |||
63 | input : 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 | |||
72 | stmtlist: 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 | |||
88 | stmt : simple | ||
89 | | block | ||
90 | ; | ||
91 | |||
92 | simple : 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 | |||
113 | block : 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 | |||
122 | tag : /* 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 | |||
140 | vallist : 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 | |||
163 | vlist : 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 '}' | ||