1 : %{
2 : /*
3 : Copyright (C) 2007, Bruce Ediger
4 :
5 : This file is part of cl.
6 :
7 : cl is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 2 of the License, or
10 : (at your option) any later version.
11 :
12 : cl is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with cl; if not, write to the Free Software
19 : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 :
21 : */
22 :
23 : #include <stdio.h>
24 : #include <stdlib.h>
25 : #include <errno.h> /* errno */
26 : #include <string.h> /* strlen(), strerror() */
27 :
28 : #include <hashtable.h>
29 : #include <atom.h>
30 : #include <node.h>
31 :
32 : #include "y.tab.h"
33 : int lineno = 0;
34 :
35 : const char *current_input_stream;
36 :
37 : char *unescape_string(char *s);
38 : void push_and_open(const char *filename);
39 :
40 : struct stream_node {
41 : #ifdef FLEX_SCANNER
42 : YY_BUFFER_STATE stream;
43 : #else
44 : FILE *stream;
45 : #endif
46 : struct stream_node *next;
47 : const char *old_filename;
48 : int old_lineno;
49 : };
50 :
51 : struct stream_node *file_stack = NULL;
52 :
53 : void set_yyin_stdin(void);
54 :
55 : extern int S_as_combinator;
56 : extern int K_as_combinator;
57 : extern int I_as_combinator;
58 : extern int B_as_combinator;
59 : extern int C_as_combinator;
60 : extern int W_as_combinator;
61 : extern int T_as_combinator;
62 : extern int M_as_combinator;
63 :
64 : extern int prompting;
65 : int old_prompting = -1;
66 :
67 :
68 : %}
69 :
70 : %%
71 :
72 133 : \#.*$ { return TK_EOL; }
73 585 : \n { return TK_EOL; }
74 : \\\n { /* Just eat it. */ }
75 0 : \( { return TK_LPAREN; }
76 593 : \) { return TK_RPAREN; }
77 169 : \[ { return TK_LBRACK; }
78 169 : ] { return TK_RBRACK; }
79 58 : "def" { return TK_DEF; }
80 65 : "define" { return TK_DEF; }
81 79 : "reduce" { return TK_REDUCE; }
82 3 : "timer" { return TK_TIME; }
83 2 : "timeout" { return TK_TIMEOUT; }
84 3 : "debug" { return TK_DEBUG; }
85 2 : "step" { return TK_SINGLE_STEP; }
86 3 : "trace" { return TK_TRACE; }
87 3 : "elaborate" { return TK_ELABORATE; }
88 1 : "load" { return TK_LOAD; }
89 : "curry"|"turner"|"grz"|"tromp"|"btmk" {
90 88 : yylval.identifier = Atom_string(yytext);
91 88 : return TK_ALGORITHM_NAME;
92 : }
93 0 : "abstraction" { return TK_SET_BRACKET_ABSTRACTION; }
94 0 : "count" { return TK_MAX_COUNT; }
95 2 : [0-9][0-9]* { yylval.numerical_constant = strtol(yytext, NULL, 10);
96 2 : return NUMERICAL_CONSTANT; }
97 : \"(\\.|[^\\"])*\" {
98 : char *tmp;
99 1 : tmp = unescape_string(yytext);
100 1 : yylval.string_constant = Atom_string(tmp);
101 1 : free(tmp);
102 1 : return STRING_LITERAL;
103 : }
104 182 : S { if (S_as_combinator) { yylval.cn = COMB_S; return TK_PRIMITIVE;}
105 0 : else {yylval.identifier = Atom_string(yytext); return TK_IDENTIFIER;}
106 : }
107 136 : K { if (K_as_combinator) { yylval.cn = COMB_K; return TK_PRIMITIVE;}
108 0 : else {yylval.identifier = Atom_string(yytext); return TK_IDENTIFIER;}
109 : }
110 199 : I { if (I_as_combinator) {yylval.cn = COMB_I; return TK_PRIMITIVE;}
111 0 : else {yylval.identifier = Atom_string(yytext); return TK_IDENTIFIER;}
112 : }
113 144 : B { if (B_as_combinator) {yylval.cn = COMB_B; return TK_PRIMITIVE;}
114 0 : else {yylval.identifier = Atom_string(yytext); return TK_IDENTIFIER;}
115 : }
116 99 : C { if (C_as_combinator) {yylval.cn = COMB_C; return TK_PRIMITIVE;}
117 0 : else {yylval.identifier = Atom_string(yytext); return TK_IDENTIFIER;}
118 : }
119 14 : W { if (W_as_combinator) {yylval.cn = COMB_W; return TK_PRIMITIVE;}
120 0 : else {yylval.identifier = Atom_string(yytext); return TK_IDENTIFIER;}
121 : }
122 9 : T { if (T_as_combinator) {yylval.cn = COMB_T; return TK_PRIMITIVE;}
123 0 : else {yylval.identifier = Atom_string(yytext); return TK_IDENTIFIER;}
124 : }
125 14 : M { if (M_as_combinator) {yylval.cn = COMB_M; return TK_PRIMITIVE;}
126 0 : else {yylval.identifier = Atom_string(yytext); return TK_IDENTIFIER;}
127 : }
128 1309 : [a-zA-Z][a-zA-Z_0-9]* { yylval.identifier = Atom_string(yytext); return TK_IDENTIFIER; }
129 : . { /* Just eat it. */ }
130 1929 :
131 0 : %%
132 0 :
133 : char *
134 : unescape_string(char *s)
135 : {
136 1 : char *n = NULL;
137 1 : if (s)
138 1 : {
139 : int i, j, l;
140 : if ('"' == s[0])
141 1 : ++s;
142 1 : if ('"' == s[strlen(s) - 1])
143 1 : s[strlen(s) - 1] = '\0';
144 1 : n = malloc(strlen(s) + 1);
145 1 : l = strlen(s);
146 1 : for (i = 0, j = 0; i < l; ++i)
147 18 : {
148 : if ('\\' == s[i])
149 17 : {
150 : ++i;
151 0 : switch (s[i])
152 0 : {
153 : /* XXX - doesn't do '\0' or other numerical escapes */
154 : case 't': n[j++] = '\t'; break;
155 0 : case 'r': n[j++] = '\r'; break;
156 0 : case 'n': n[j++] = '\n'; break;
157 0 : case '\\': n[j++] = '\\'; break;
158 0 : default:
159 : n[j++] = s[i];
160 0 : break;
161 : }
162 : } else {
163 : n[j++] = s[i];
164 17 : }
165 : }
166 : n[j] = '\0';
167 1 : }
168 : return n;
169 1 : }
170 :
171 : void
172 : push_and_open(const char *filename)
173 : {
174 1 : FILE *fin;
175 : extern FILE *yyin;
176 : extern int lineno;
177 : extern const char *current_input_stream;
178 :
179 : if (NULL != (fin = fopen(filename, "r")))
180 1 : {
181 : struct stream_node *n;
182 : n = malloc(sizeof(*n));
183 1 : #ifdef FLEX_SCANNER
184 : n->stream = YY_CURRENT_BUFFER;
185 1 : yyin = fin;
186 1 : yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
187 1 : #else
188 : n->stream = yyin;
189 : yyin = fin;
190 : #endif
191 : n->next = file_stack;
192 1 : n->old_filename = current_input_stream;
193 1 : n->old_lineno = lineno;
194 1 : current_input_stream = filename;
195 1 : file_stack = n;
196 1 : lineno = 0;
197 1 : if (old_prompting < 0)
198 1 : old_prompting = prompting;
199 1 : prompting = 0;
200 1 : } else {
201 : fprintf(stderr, "Could not open \"%s\" for read: %s\n",
202 0 : filename, strerror(errno));
203 : }
204 : }
205 1 :
206 : void
207 : set_yyin_stdin(void)
208 : {
209 56 : yyin = stdin;
210 56 : #ifdef FLEX_SCANNER
211 : yy_delete_buffer(YY_CURRENT_BUFFER);
212 56 : yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
213 56 : #endif
214 : }
215 56 :
216 : void
217 : set_yyin(const char *filename)
218 : {
219 0 : FILE *fin;
220 :
221 : if (NULL != (fin = fopen(filename, "r")))
222 0 : {
223 : yyin = fin;
224 0 : #ifdef FLEX_SCANNER
225 : yy_delete_buffer(YY_CURRENT_BUFFER);
226 0 : yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
227 0 : #endif
228 : current_input_stream = filename;
229 0 : lineno = 0;
230 0 : } else {
231 : fprintf(stderr, "Could not open \"%s\" for read: %s\n",
232 0 : filename, strerror(errno));
233 : }
234 : }
235 0 :
236 : void
237 : reset_yyin(void)
238 : {
239 0 : if (yyin)
240 0 : fclose(yyin);
241 0 : yyin = NULL;
242 0 : #ifdef FLEX_SCANNER
243 : yy_delete_buffer(YY_CURRENT_BUFFER);
244 0 : #endif
245 : }
246 0 :
247 : int
248 : yywrap()
249 : {
250 57 : extern FILE *yyin;
251 : extern int lineno;
252 : extern struct stream_node *file_stack;
253 :
254 : int r = 1;
255 57 : if (file_stack)
256 57 : {
257 : struct stream_node *tmp = file_stack->next;
258 1 : fclose(yyin);
259 1 : #ifdef FLEX_SCANNER
260 : yy_delete_buffer(YY_CURRENT_BUFFER);
261 1 : yy_switch_to_buffer(file_stack->stream);
262 1 : #else
263 : yyin = file_stack->stream;
264 : #endif
265 : current_input_stream = file_stack->old_filename;
266 1 : lineno = file_stack->old_lineno;
267 1 : file_stack->stream = NULL;
268 1 : file_stack->next = NULL;
269 1 : free(file_stack);
270 1 : file_stack = tmp;
271 1 : r = 0;
272 1 : }
273 : if (!file_stack)
274 57 : {
275 : if (old_prompting > 0)
276 57 : {
277 : prompting = 1;
278 0 : old_prompting = -1;
279 0 : printf("CL> ");
280 0 : }
281 : }
282 : return r;
283 57 : }
|