update for win32 compatibility
[libfirm] / ir / libcore / lc_config_parser.y
1
2 %name-prefix="_lc_opt_"
3
4 %{
5
6 /*
7   libcore: library for basic data structures and algorithms.
8   Copyright (C) 2005  IPD Goos, Universit"at Karlsruhe, Germany
9
10   This library is free software; you can redistribute it and/or
11   modify it under the terms of the GNU Lesser General Public
12   License as published by the Free Software Foundation; either
13   version 2.1 of the License, or (at your option) any later version.
14
15   This library is distributed in the hope that it will be useful,
16   but WITHOUT ANY WARRANTY; without even the implied warranty of
17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18   Lesser General Public License for more details.
19
20   You should have received a copy of the GNU Lesser General Public
21   License along with this library; if not, write to the Free Software
22   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23 */
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <string.h>
29
30 #include "lc_opts_t.h"
31 #include "lc_parser_t.h"
32
33 static void group_open(void);
34 static void group_close(void);
35 static void lc_opt_set(void);
36 static void path_push(text_t text);
37
38 void PMANGLE(error)(const char *str);
39 int PMANGLE(linenr);
40
41 %}
42
43 %union {
44         text_t text;
45         int num;
46 }
47
48 %token SEP DATA
49 %token <text> IDENT
50
51 %%
52
53 main: dseq ;
54
55 decl: group
56         | option
57         ;
58
59 decls: decls decl
60         | decl
61         ;
62
63 dseq: decls | ;
64
65 group: path { group_open(); } '{' dseq '}' { group_close(); } ;
66
67 option: path DATA { lc_opt_set(); } ;
68
69 path: path SEP IDENT { path_push($3); }
70         | IDENT { path_push($1); }
71         ;
72
73 %%
74
75 static lc_opt_error_handler_t *handler;
76 static struct obstack obst;
77 const char *optfilename = "";
78
79 void PMANGLE(error)(const char *str)
80 {
81         fprintf(stderr, "At line %d: %s\n", PMANGLE(linenr), str);
82 }
83
84 static const char *path_stack[128];
85 static int path_sp = 0;
86
87 static lc_opt_entry_t *grp_stack[128];
88 static int grp_sp = 0;
89 #define CURR_GRP (grp_stack[grp_sp - 1])
90
91 void lc_opt_init_parser(const char *filename, lc_opt_error_handler_t *err_handler)
92 {
93         PMANGLE(linenr) = 1;
94         obstack_init(&obst);
95         handler = err_handler;
96         optfilename = filename;
97         grp_stack[grp_sp++] = lc_opt_root_grp();
98 }
99
100 void _lc_opt_add_to_data_char(char c)
101 {
102         obstack_1grow(&obst, c);
103 }
104
105 static void path_push(text_t text)
106 {
107         obstack_grow0(&obst, text.str, text.len);
108         path_stack[path_sp++] = obstack_finish(&obst);
109 }
110
111 static void path_free(void)
112 {
113         obstack_free(&obst, (void *) path_stack[0]);
114         path_sp = 0;
115 }
116
117 static void group_open(void)
118 {
119         lc_opt_err_info_t err;
120         lc_opt_entry_t *grp = lc_opt_resolve_grp(CURR_GRP, path_stack, path_sp, &err);
121
122         path_free();
123
124         grp_stack[grp_sp++] = grp;
125 }
126
127 static void group_close(void)
128 {
129         grp_sp--;
130 }
131
132 static void lc_opt_set(void)
133 {
134         char *str = obstack_finish(&obst);
135
136         lc_opt_err_info_t err;
137         lc_opt_entry_t *opt = lc_opt_resolve_opt(CURR_GRP, path_stack, path_sp, &err);
138         lc_opt_raise_error(&err, handler, "At %s(%d): ", optfilename, PMANGLE(linenr));
139
140         lc_opt_occurs(opt, str, &err);
141         lc_opt_raise_error(&err, handler, "At %s(%d): ", optfilename, PMANGLE(linenr));
142
143         obstack_free(&obst, str);
144         path_free();
145 }