improve constant loading. Still sucks, but oh well
[oota-llvm.git] / utils / Burg / lex.c
1 char 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 "gram.tab.h"
9
10 static char buf[BUFSIZ];
11
12 static int yyline = 1;
13
14 typedef int (*ReadFn) ARGS((void));
15
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));
22
23 static char *
24 StrCopy(s) char *s;
25 {
26   char *t = (char *)zalloc(strlen(s) + 1);
27   strcpy(t,s);
28   return t;
29 }
30
31 static int
32 simple_get()
33 {
34   int ch;
35   if ((ch = getchar()) == '\n') {
36     yyline++;
37   }
38   return ch;
39 }
40
41 static int
42 code_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
54 void
55 yypurge()
56 {
57   while (code_get() != EOF) ;
58 }
59
60
61 static void
62 ReadCharString(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
83 static void
84 ReadOldComment(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
106 static void
107 ReadCodeBlock()
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
142 static int done;
143 void
144 yyfinished()
145 {
146   done = 1;
147 }
148
149 int
150 yylex()
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
248 void yyerror1(const char *str)
249 {
250   fprintf(stderr, "line %d: %s", yyline, str);
251 }
252
253 void
254 yyerror(const char *str)
255 {
256   yyerror1(str);
257   fprintf(stderr, "\n");
258   exit(1);
259 }