blob: 3d6c5af5c48131b1c08ad2689978d1477b533b55 [file] [log] [blame]
Chris Lattner633a5b12002-09-17 23:03:30 +00001char rcsid_lex[] = "$Id$";
2
3#include <ctype.h>
4#include <stdio.h>
5#include <string.h>
6#include "b.h"
7#include "fe.h"
8#include "y.tab.h"
9
10static char buf[BUFSIZ];
11
12static int yyline = 1;
13
14typedef int (*ReadFn) ARGS((void));
15
16static char *StrCopy ARGS((char *));
17static int code_get ARGS((void));
18static int simple_get ARGS((void));
19static void ReadCharString ARGS((ReadFn, int));
20static void ReadCodeBlock ARGS((void));
21static void ReadOldComment ARGS((ReadFn));
22
23static char *
24StrCopy(s) char *s;
25{
26 char *t = (char *)zalloc(strlen(s) + 1);
27 strcpy(t,s);
28 return t;
29}
30
31static int
32simple_get()
33{
34 int ch;
35 if ((ch = getchar()) == '\n') {
36 yyline++;
37 }
38 return ch;
39}
40
41static int
42code_get()
43{
44 int ch;
45 if ((ch = getchar()) == '\n') {
46 yyline++;
47 }
48 if (ch != EOF) {
49 fputc(ch, outfile);
50 }
51 return ch;
52}
53
54void
55yypurge()
56{
57 while (code_get() != EOF) ;
58}
59
60
61static void
62ReadCharString(rdfn, which) ReadFn rdfn; int which;
63{
64 int ch;
65 int backslash = 0;
66 int firstline = yyline;
67
68 while ((ch = rdfn()) != EOF) {
69 if (ch == which && !backslash) {
70 return;
71 }
72 if (ch == '\\' && !backslash) {
73 backslash = 1;
74 } else {
75 backslash = 0;
76 }
77 }
78 yyerror1("Unexpected EOF in string on line ");
79 fprintf(stderr, "%d\n", firstline);
80 exit(1);
81}
82
83static void
84ReadOldComment(rdfn) ReadFn rdfn;
85{
86 /* will not work for comments delimiter in string */
87
88 int ch;
89 int starred = 0;
90 int firstline = yyline;
91
92 while ((ch = rdfn()) != EOF) {
93 if (ch == '*') {
94 starred = 1;
95 } else if (ch == '/' && starred) {
96 return;
97 } else {
98 starred = 0;
99 }
100 }
101 yyerror1("Unexpected EOF in comment on line ");
102 fprintf(stderr, "%d\n", firstline);
103 exit(1);
104}
105
106static void
107ReadCodeBlock()
108{
109 int ch;
110 int firstline = yyline;
111
112 while ((ch = getchar()) != EOF) {
113 if (ch == '%') {
114 ch = getchar();
115 if (ch != '}') {
116 yyerror("bad %%");
117 }
118 return;
119 }
120 fputc(ch, outfile);
121 if (ch == '\n') {
122 yyline++;
123 }
124 if (ch == '"' || ch == '\'') {
125 ReadCharString(code_get, ch);
126 } else if (ch == '/') {
127 ch = getchar();
128 if (ch == '*') {
129 fputc(ch, outfile);
130 ReadOldComment(code_get);
131 continue;
132 } else {
133 ungetc(ch, stdin);
134 }
135 }
136 }
137 yyerror1("Unclosed block of C code started on line ");
138 fprintf(stderr, "%d\n", firstline);
139 exit(1);
140}
141
142static int done;
143void
144yyfinished()
145{
146 done = 1;
147}
148
149int
150yylex()
151{
152 int ch;
153 char *ptr = buf;
154
155 if (done) return 0;
156 while ((ch = getchar()) != EOF) {
157 switch (ch) {
158 case ' ':
159 case '\f':
160 case '\t':
161 continue;
162 case '\n':
163 yyline++;
164 continue;
165 case '(':
166 case ')':
167 case ',':
168 case ':':
169 case ';':
170 case '=':
171 return(ch);
172 case '/':
173 ch = getchar();
174 if (ch == '*') {
175 ReadOldComment(simple_get);
176 continue;
177 } else {
178 ungetc(ch, stdin);
179 yyerror("illegal char /");
180 continue;
181 }
182 case '%':
183 ch = getchar();
184 switch (ch) {
185 case '%':
186 return (K_PPERCENT);
187 case '{':
188 ReadCodeBlock();
189 continue;
190 case 's':
191 case 'g':
192 case 't':
193 do {
194 if (ptr >= &buf[BUFSIZ]) {
195 yyerror("ID too long");
196 return(ERROR);
197 } else {
198 *ptr++ = ch;
199 }
200 ch = getchar();
201 } while (isalpha(ch) || isdigit(ch) || ch == '_');
202 ungetc(ch, stdin);
203 *ptr = '\0';
204 if (!strcmp(buf, "term")) return K_TERM;
205 if (!strcmp(buf, "start")) return K_START;
206 if (!strcmp(buf, "gram")) return K_GRAM;
207 yyerror("illegal character after %%");
208 continue;
209 default:
210 yyerror("illegal character after %%");
211 continue;
212 }
213 default:
214 if (isalpha(ch) ) {
215 do {
216 if (ptr >= &buf[BUFSIZ]) {
217 yyerror("ID too long");
218 return(ERROR);
219 } else {
220 *ptr++ = ch;
221 }
222 ch = getchar();
223 } while (isalpha(ch) || isdigit(ch) || ch == '_');
224 ungetc(ch, stdin);
225 *ptr = '\0';
226 yylval.y_string = StrCopy(buf);
227 return(ID);
228 }
229 if (isdigit(ch)) {
230 int val=0;
231 do {
232 val *= 10;
233 val += (ch - '0');
234 ch = getchar();
235 } while (isdigit(ch));
236 ungetc(ch, stdin);
237 yylval.y_int = val;
238 return(INT);
239 }
240 yyerror1("illegal char ");
241 fprintf(stderr, "(\\%03o)\n", ch);
242 exit(1);
243 }
244 }
245 return(0);
246}
247
248void
249yyerror1(str) char *str;
250{
251 fprintf(stderr, "line %d: %s", yyline, str);
252}
253
254void
255yyerror(str) char *str;
256{
257 yyerror1(str);
258 fprintf(stderr, "\n");
259 exit(1);
260}