Added llvmgcc version to allow tests to be xfailed by frontend version.
[llvm-complete.git] / utils / Burg / lex.c
blob4fec1bfdb7537ae847e0e371d1818c1fed823a8e
1 char rcsid_lex[] = "$Id$";
3 #include <ctype.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include "b.h"
7 #include "fe.h"
8 #include "gram.tab.h"
10 static char buf[BUFSIZ];
12 static int yyline = 1;
14 typedef int (*ReadFn) ARGS((void));
16 static char *StrCopy ARGS((char *));
17 static int code_get ARGS((void));
18 static int simple_get ARGS((void));
19 static void ReadCharString ARGS((ReadFn, int));
20 static void ReadCodeBlock ARGS((void));
21 static void ReadOldComment ARGS((ReadFn));
23 static char *
24 StrCopy(s) char *s;
26 char *t = (char *)zalloc(strlen(s) + 1);
27 strcpy(t,s);
28 return t;
31 static int
32 simple_get()
34 int ch;
35 if ((ch = getchar()) == '\n') {
36 yyline++;
38 return ch;
41 static int
42 code_get()
44 int ch;
45 if ((ch = getchar()) == '\n') {
46 yyline++;
48 if (ch != EOF) {
49 fputc(ch, outfile);
51 return ch;
54 void
55 yypurge()
57 while (code_get() != EOF) ;
61 static void
62 ReadCharString(rdfn, which) ReadFn rdfn; int which;
64 int ch;
65 int backslash = 0;
66 int firstline = yyline;
68 while ((ch = rdfn()) != EOF) {
69 if (ch == which && !backslash) {
70 return;
72 if (ch == '\\' && !backslash) {
73 backslash = 1;
74 } else {
75 backslash = 0;
78 yyerror1("Unexpected EOF in string on line ");
79 fprintf(stderr, "%d\n", firstline);
80 exit(1);
83 static void
84 ReadOldComment(rdfn) ReadFn rdfn;
86 /* will not work for comments delimiter in string */
88 int ch;
89 int starred = 0;
90 int firstline = yyline;
92 while ((ch = rdfn()) != EOF) {
93 if (ch == '*') {
94 starred = 1;
95 } else if (ch == '/' && starred) {
96 return;
97 } else {
98 starred = 0;
101 yyerror1("Unexpected EOF in comment on line ");
102 fprintf(stderr, "%d\n", firstline);
103 exit(1);
106 static void
107 ReadCodeBlock()
109 int ch;
110 int firstline = yyline;
112 while ((ch = getchar()) != EOF) {
113 if (ch == '%') {
114 ch = getchar();
115 if (ch != '}') {
116 yyerror("bad %%");
118 return;
120 fputc(ch, outfile);
121 if (ch == '\n') {
122 yyline++;
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);
137 yyerror1("Unclosed block of C code started on line ");
138 fprintf(stderr, "%d\n", firstline);
139 exit(1);
142 static int done;
143 void
144 yyfinished()
146 done = 1;
150 yylex()
152 int ch;
153 char *ptr = buf;
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;
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;
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;
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;
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);
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);
240 yyerror1("illegal char ");
241 fprintf(stderr, "(\\%03o)\n", ch);
242 exit(1);
245 return(0);
248 void yyerror1(const char *str)
250 fprintf(stderr, "line %d: %s", yyline, str);
253 void
254 yyerror(const char *str)
256 yyerror1(str);
257 fprintf(stderr, "\n");
258 exit(1);