aboutsummaryrefslogtreecommitdiff
path: root/src/meta1-gram.y
diff options
context:
space:
mode:
Diffstat (limited to 'src/meta1-gram.y')
-rw-r--r--src/meta1-gram.y217
1 files changed, 217 insertions, 0 deletions
diff --git a/src/meta1-gram.y b/src/meta1-gram.y
new file mode 100644
index 0000000..8ddcbfb
--- /dev/null
+++ b/src/meta1-gram.y
@@ -0,0 +1,217 @@
1%{
2/* MeTA1 configuration parser for Grecs.
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 <errno.h>
22#include <string.h>
23#include "grecs.h"
24
25int yylex(void);
26int yyerror(char *s);
27
28static struct grecs_node *parse_tree;
29extern int yy_flex_debug;
30%}
31
32%union {
33 struct {
34 grecs_locus_t locus;
35 char *string;
36 } ident;
37 char *string;
38 grecs_value_t svalue, *pvalue;
39 struct grecs_list *list;
40 struct { struct grecs_node *head, *tail; } node_list;
41 struct grecs_node *node;
42}
43
44%token <ident> META1_IDENT
45%token <string> META1_STRING
46%type <node> stmt simple block
47%type <node_list> stmtlist
48%type <pvalue> tag value
49%type <string> string slist
50%type <list> slist0
51%type <list> values list
52%%
53
54input : stmtlist
55 {
56 parse_tree = grecs_node_create(grecs_node_root,
57 &grecs_current_locus);
58 parse_tree->v.texttab = grecs_text_table();
59 grecs_node_bind(parse_tree, $1.head, 1);
60 }
61 ;
62
63stmtlist: stmt
64 {
65 $$.head = $$.tail = $1;
66 }
67 | stmtlist stmt
68 {
69 grecs_node_bind($1.tail, $2, 0);
70 }
71 ;
72
73stmt : simple
74 | block
75 ;
76
77simple : META1_IDENT '=' value opt_sc
78 {
79 $$ = grecs_node_create(grecs_node_stmt,
80 &$1.locus);
81 $$->ident = $1.string;
82 $$->v.value = $3;
83 }
84 ;
85
86block : META1_IDENT tag '{' stmtlist '}' opt_sc
87 {
88 $$ = grecs_node_create(grecs_node_block,
89 &$1.locus);
90 $$->ident = $1.string;
91 $$->v.value = $2;
92 grecs_node_bind($$, $4.head, 1);
93 }
94 ;
95
96tag : /* empty */
97 {
98 $$ = NULL;
99 }
100 | META1_IDENT
101 {
102 $$ = grecs_malloc(sizeof($$[0]));
103 $$->type = GRECS_TYPE_STRING;
104 $$->v.string = $1.string;
105 }
106 ;
107
108value : string
109 {
110 $$ = grecs_malloc(sizeof($$[0]));
111 $$->type = GRECS_TYPE_STRING;
112 $$->v.string = $1;
113 }
114 | list
115 {
116 $$ = grecs_malloc(sizeof($$[0]));
117 $$->type = GRECS_TYPE_LIST;
118 $$->v.list = $1;
119 }
120 ;
121
122string : META1_IDENT
123 {
124 $$ = $1.string;
125 }
126 | slist
127 ;
128
129slist : slist0
130 {
131 struct grecs_list_entry *ep;
132
133 grecs_line_begin();
134 for (ep = $1->head; ep; ep = ep->next) {
135 grecs_line_add(ep->data, strlen(ep->data));
136 free(ep->data);
137 ep->data = NULL;
138 }
139 $$ = grecs_line_finish();
140 grecs_list_free($1);
141 }
142
143slist0 : META1_STRING
144 {
145 $$ = grecs_list_create();
146 grecs_list_append($$, $1);
147 }
148 | slist0 META1_STRING
149 {
150 grecs_list_append($1, $2);
151 $$ = $1;
152 }
153 ;
154
155list : '{' values '}'
156 {
157 $$ = $2;
158 }
159 | '{' values ',' '}'
160 {
161 $$ = $2;
162 }
163 ;
164
165values : value
166 {
167 $$ = grecs_value_list_create();
168 grecs_list_append($$, $1);
169 }
170 | values ',' value
171 {
172 grecs_list_append($1, $3);
173 $$ = $1;
174 }
175 ;
176
177opt_sc : /* empty */
178 | ';'
179 ;
180
181%%
182int
183yyerror(char *s)
184{
185 grecs_error(&grecs_current_locus, 0, "%s", s);
186 return 0;
187}
188
189struct grecs_node *
190grecs_meta1_parser(const char *name, int traceflags)
191{
192 int rc;
193 FILE *fp;
194
195 fp = fopen(name, "r");
196 if (!fp) {
197 grecs_error(NULL, errno, _("Cannot open `%s'"), name);
198 return NULL;
199 }
200 yyset_in(fp);
201
202 yy_flex_debug = traceflags & GRECS_TRACE_LEX;
203 yydebug = traceflags & GRECS_TRACE_GRAM;
204 parse_tree = NULL;
205 grecs_line_acc_create();
206 rc = yyparse();
207 fclose(fp);
208 if (grecs_error_count)
209 rc = 1;
210 grecs_line_acc_free();
211 if (rc) {
212 grecs_tree_free(parse_tree);
213 parse_tree = NULL;
214 }
215 return parse_tree;
216}
217

Return to:

Send suggestions and report system problems to the System administrator.