70ab698ab88bf1b69f0a209c4eb333f4033181d2
[m6w6/ext-psi] / src / parser.re
1 #include <stdio.h>
2 #include <assert.h>
3
4 #include "parser.h"
5 #include "parser_proc.h"
6
7 void *PSI_ParserProcAlloc(void*(unsigned long));
8 void PSI_ParserProcFree(void*, void(*)(void*));
9 void PSI_ParserProc(void *, token_t, PSI_Token *, PSI_Parser *);
10 void PSI_ParserProcTrace(FILE *, const char*);
11
12 PSI_Parser *PSI_ParserInit(PSI_Parser *P, const char *filename, psi_error_cb error, unsigned flags)
13 {
14 FILE *fp;
15
16 if (!P) {
17 P = malloc(sizeof(*P));
18 }
19 memset(P, 0, sizeof(*P));
20
21 fp = fopen(filename, "r");
22
23 if (!fp) {
24 perror(filename);
25 return NULL;
26 }
27
28 if (!P) {
29 P = malloc(sizeof(*P));
30 }
31 memset(P, 0, sizeof(*P));
32
33 P->psi.file.fn = strdup(filename);
34 P->fp = fp;
35 P->col = 1;
36 P->line = 1;
37 P->error = error;
38 P->flags = flags;
39
40 P->proc = PSI_ParserProcAlloc(malloc);
41 if (flags & PSI_PARSER_DEBUG) {
42 PSI_ParserProcTrace(stderr, "PSI> ");
43 }
44
45 PSI_ParserFill(P, 0);
46
47 return P;
48 }
49
50 size_t PSI_ParserFill(PSI_Parser *P, size_t n)
51 {
52 if (P->flags & PSI_PARSER_DEBUG) {
53 fprintf(stderr, "PSI> Fill: n=%zu\n", n);
54 }
55 if (!n) {
56 P->cur = P->tok = P->lim = P->mrk = P->buf;
57 P->eof = NULL;
58 }
59
60 if (!P->eof) {
61 size_t consumed = P->tok - P->buf;
62 size_t reserved = P->lim - P->tok;
63 size_t available = BSIZE - reserved;
64 size_t didread;
65
66 if (consumed) {
67 memmove(P->buf, P->tok, reserved);
68 P->tok -= consumed;
69 P->cur -= consumed;
70 P->lim -= consumed;
71 P->mrk -= consumed;
72 }
73
74 didread = fread(P->lim, 1, available, P->fp);
75 P->lim += didread;
76 if (didread < available) {
77 P->eof = P->lim;
78 }
79
80 if (P->flags & PSI_PARSER_DEBUG) {
81 fprintf(stderr, "PSI> Fill: consumed=%zu reserved=%zu available=%zu didread=%zu\n",
82 consumed, reserved, available, didread);
83 }
84 }
85 if (P->flags & PSI_PARSER_DEBUG) {
86 fprintf(stderr, "PSI> Fill: avail=%zu\n", P->lim - P->cur);
87 }
88 return P->lim - P->cur;
89 }
90
91 void PSI_ParserParse(PSI_Parser *P, PSI_Token *T)
92 {
93 if (T) {
94 PSI_ParserProc(P->proc, T->type, T, P);
95 } else {
96 PSI_ParserProc(P->proc, 0, NULL, P);
97 }
98 }
99
100 void PSI_ParserDtor(PSI_Parser *P)
101 {
102 PSI_ParserProcFree(P->proc, free);
103
104 if (P->fp) {
105 fclose(P->fp);
106 }
107
108 PSI_DataDtor((PSI_Data *) P);
109
110 memset(P, 0, sizeof(*P));
111 }
112
113 void PSI_ParserFree(PSI_Parser **P)
114 {
115 if (*P) {
116 PSI_ParserDtor(*P);
117 free(*P);
118 *P = NULL;
119 }
120 }
121
122 /*!max:re2c*/
123 #define BSIZE 256
124
125 #if BSIZE < YYMAXFILL
126 # error BSIZE must be greater than YYMAXFILL
127 #endif
128
129 #define PSI_T(n) \
130 (n) == PSI_T_NAME ? "NAME" : \
131 (n) == PSI_T_PLUS ? "PLUS" : \
132 (n) == PSI_T_MINUS ? "MINUS" : \
133 (n) == PSI_T_SLASH ? "SLASH" : \
134 (n) == PSI_T_ASTERISK ? "ASTERISK" : \
135 (n) == PSI_T_TEMP ? "TEMP" : \
136 (n) == PSI_T_FREE ? "FREE" : \
137 (n) == PSI_T_SET ? "SET" : \
138 (n) == PSI_T_LET ? "LET" : \
139 (n) == PSI_T_RETURN ? "RETURN" : \
140 (n) == PSI_T_LIB ? "LIB" : \
141 (n) == PSI_T_INT ? "INT" : \
142 (n) == PSI_T_UNSIGNED ? "UNSIGNED" : \
143 (n) == PSI_T_EOF ? "EOF" : \
144 (n) == PSI_T_QUOTED_STRING ? "QUOTED_STRING" : \
145 (n) == PSI_T_EOS ? "EOS" : \
146 (n) == PSI_T_STRUCT ? "STRUCT" : \
147 (n) == PSI_T_LBRACE ? "LBRACE" : \
148 (n) == PSI_T_RBRACE ? "RBRACE" : \
149 (n) == PSI_T_COLON ? "COLON" : \
150 (n) == PSI_T_LPAREN ? "LPAREN" : \
151 (n) == PSI_T_NUMBER ? "NUMBER" : \
152 (n) == PSI_T_RPAREN ? "RPAREN" : \
153 (n) == PSI_T_BOOL ? "BOOL" : \
154 (n) == PSI_T_FLOAT ? "FLOAT" : \
155 (n) == PSI_T_STRING ? "STRING" : \
156 (n) == PSI_T_CONST ? "CONST" : \
157 (n) == PSI_T_NSNAME ? "NSNAME" : \
158 (n) == PSI_T_EQUALS ? "EQUALS" : \
159 (n) == PSI_T_TYPEDEF ? "TYPEDEF" : \
160 (n) == PSI_T_VOID ? "VOID" : \
161 (n) == PSI_T_LBRACKET ? "LBRACKET" : \
162 (n) == PSI_T_RBRACKET ? "RBRACKET" : \
163 (n) == PSI_T_COMMA ? "COMMA" : \
164 (n) == PSI_T_ELLIPSIS ? "ELLIPSIS" : \
165 (n) == PSI_T_DOUBLE ? "DOUBLE" : \
166 (n) == PSI_T_INT8 ? "INT8" : \
167 (n) == PSI_T_UINT8 ? "UINT8" : \
168 (n) == PSI_T_INT16 ? "INT16" : \
169 (n) == PSI_T_UINT16 ? "UINT16" : \
170 (n) == PSI_T_INT32 ? "INT32" : \
171 (n) == PSI_T_UINT32 ? "UINT32" : \
172 (n) == PSI_T_INT64 ? "INT64" : \
173 (n) == PSI_T_UINT64 ? "UINT64" : \
174 (n) == PSI_T_FUNCTION ? "FUNCTION" : \
175 (n) == PSI_T_NULL ? "NULL" : \
176 (n) == PSI_T_TRUE ? "TRUE" : \
177 (n) == PSI_T_FALSE ? "FALSE" : \
178 (n) == PSI_T_DOLLAR ? "DOLLAR" : \
179 (n) == PSI_T_CALLOC ? "CALLOC" : \
180 (n) == PSI_T_OBJVAL ? "OBJVAL" : \
181 (n) == PSI_T_ARRVAL ? "ARRVAL" : \
182 (n) == PSI_T_PATHVAL ? "PATHVAL" : \
183 (n) == PSI_T_STRLEN ? "STRLEN" : \
184 (n) == PSI_T_STRVAL ? "STRVAL" : \
185 (n) == PSI_T_FLOATVAL ? "FLOATVAL" : \
186 (n) == PSI_T_INTVAL ? "INTVAL" : \
187 (n) == PSI_T_BOOLVAL ? "BOOLVAL" : \
188 (n) == PSI_T_TO_OBJECT ? "TO_OBJECT" : \
189 (n) == PSI_T_TO_ARRAY ? "TO_ARRAY" : \
190 (n) == PSI_T_TO_STRING ? "TO_STRING" : \
191 (n) == PSI_T_TO_INT ? "TO_INT" : \
192 (n) == PSI_T_TO_FLOAT ? "TO_FLOAT" : \
193 (n) == PSI_T_TO_BOOL ? "TO_BOOL" : \
194 (n) == PSI_T_MIXED ? "MIXED" : \
195 (n) == PSI_T_ARRAY ? "ARRAY" : \
196 (n) == PSI_T_OBJECT ? "OBJECT" : \
197 (n) == PSI_T_AMPERSAND ? "AMPERSAND" : \
198 <UNKNOWN>
199
200 #define RETURN(t) do { \
201 P->num = t; \
202 if (P->flags & PSI_PARSER_DEBUG) { \
203 fprintf(stderr, "PSI> TOKEN: %d %.*s (EOF=%d %s:%u:%u)\n", \
204 P->num, (int) (P->cur-P->tok), P->tok, P->num == PSI_T_EOF, \
205 P->psi.file.fn, P->line, P->col); \
206 } \
207 return t; \
208 } while(1)
209
210 #define ADDCOLS \
211 P->col += P->cur - P->tok
212
213 #define NEWLINE \
214 P->col = 1; \
215 ++P->line; \
216 goto nextline
217
218 token_t PSI_ParserScan(PSI_Parser *P)
219 {
220 for (;;) {
221 ADDCOLS;
222 nextline:
223 P->tok = P->cur;
224 /*!re2c
225 re2c:indent:top = 2;
226 re2c:define:YYCTYPE = "unsigned char";
227 re2c:define:YYCURSOR = P->cur;
228 re2c:define:YYLIMIT = P->lim;
229 re2c:define:YYMARKER = P->mrk;
230 re2c:define:YYFILL = "{ if (!PSI_ParserFill(P,@@)) RETURN(PSI_T_EOF); }";
231 re2c:yyfill:parameter = 0;
232
233 B = [^a-zA-Z0-9_];
234 W = [a-zA-Z0-9_];
235 NAME = [a-zA-Z_]W*;
236 NSNAME = (NAME)? ("\\" NAME)+;
237 QUOTED_STRING = "\"" ([^\"])+ "\"";
238 NUMBER = [+-]? [0-9]* "."? [0-9]+ ([eE] [+-]? [0-9]+)?;
239
240 ("#"|"//") .* "\n" { NEWLINE; }
241 "(" {RETURN(PSI_T_LPAREN);}
242 ")" {RETURN(PSI_T_RPAREN);}
243 ";" {RETURN(PSI_T_EOS);}
244 "," {RETURN(PSI_T_COMMA);}
245 ":" {RETURN(PSI_T_COLON);}
246 "{" {RETURN(PSI_T_LBRACE);}
247 "}" {RETURN(PSI_T_RBRACE);}
248 "[" {RETURN(PSI_T_LBRACKET);}
249 "]" {RETURN(PSI_T_RBRACKET);}
250 "=" {RETURN(PSI_T_EQUALS);}
251 "$" {RETURN(PSI_T_DOLLAR);}
252 "*" {RETURN(PSI_T_ASTERISK);}
253 "&" {RETURN(PSI_T_AMPERSAND);}
254 "+" {RETURN(PSI_T_PLUS);}
255 "-" {RETURN(PSI_T_MINUS);}
256 "/" {RETURN(PSI_T_SLASH);}
257 "..." {RETURN(PSI_T_ELLIPSIS);}
258 [\r\n] { NEWLINE; }
259 [\t ]+ { continue; }
260 'TRUE' {RETURN(PSI_T_TRUE);}
261 'FALSE' {RETURN(PSI_T_FALSE);}
262 'NULL' {RETURN(PSI_T_NULL);}
263 'MIXED' {RETURN(PSI_T_MIXED);}
264 'VOID' {RETURN(PSI_T_VOID);}
265 'BOOL' {RETURN(PSI_T_BOOL);}
266 'CHAR' {RETURN(PSI_T_CHAR);}
267 'SHORT' {RETURN(PSI_T_SHORT);}
268 'INT' {RETURN(PSI_T_INT);}
269 'LONG' {RETURN(PSI_T_LONG);}
270 'FLOAT' {RETURN(PSI_T_FLOAT);}
271 'DOUBLE' {RETURN(PSI_T_DOUBLE);}
272 'INT8_T' {RETURN(PSI_T_INT8);}
273 'UINT8_T' {RETURN(PSI_T_UINT8);}
274 'INT16_T' {RETURN(PSI_T_INT16);}
275 'UINT16_T' {RETURN(PSI_T_UINT16);}
276 'INT32_T' {RETURN(PSI_T_INT32);}
277 'UINT32_T' {RETURN(PSI_T_UINT32);}
278 'INT64_T' {RETURN(PSI_T_INT64);}
279 'UINT64_T' {RETURN(PSI_T_UINT64);}
280 'UNSIGNED' {RETURN(PSI_T_UNSIGNED);}
281 'SIGNED' {RETURN(PSI_T_SIGNED);}
282 'STRING' {RETURN(PSI_T_STRING);}
283 'ARRAY' {RETURN(PSI_T_ARRAY);}
284 'OBJECT' {RETURN(PSI_T_OBJECT);}
285 'FUNCTION' {RETURN(PSI_T_FUNCTION);}
286 'TYPEDEF' {RETURN(PSI_T_TYPEDEF);}
287 'STRUCT' {RETURN(PSI_T_STRUCT);}
288 'CONST' {RETURN(PSI_T_CONST);}
289 'LIB' {RETURN(PSI_T_LIB);}
290 'LET' {RETURN(PSI_T_LET);}
291 'SET' {RETURN(PSI_T_SET);}
292 'RETURN' {RETURN(PSI_T_RETURN);}
293 'FREE' {RETURN(PSI_T_FREE);}
294 'TEMP' {RETURN(PSI_T_TEMP);}
295 'STRLEN' {RETURN(PSI_T_STRLEN);}
296 'STRVAL' {RETURN(PSI_T_STRVAL);}
297 'PATHVAL' {RETURN(PSI_T_PATHVAL);}
298 'INTVAL' {RETURN(PSI_T_INTVAL);}
299 'FLOATVAL' {RETURN(PSI_T_FLOATVAL);}
300 'BOOLVAL' {RETURN(PSI_T_BOOLVAL);}
301 'ARRVAL' {RETURN(PSI_T_ARRVAL);}
302 'OBJVAL' {RETURN(PSI_T_OBJVAL);}
303 'CALLOC' {RETURN(PSI_T_CALLOC);}
304 'TO_OBJECT' {RETURN(PSI_T_TO_OBJECT);}
305 'TO_ARRAY' {RETURN(PSI_T_TO_ARRAY);}
306 'TO_STRING' {RETURN(PSI_T_TO_STRING);}
307 'TO_INT' {RETURN(PSI_T_TO_INT);}
308 'TO_FLOAT' {RETURN(PSI_T_TO_FLOAT);}
309 'TO_BOOL' {RETURN(PSI_T_TO_BOOL);}
310 NUMBER {RETURN(PSI_T_NUMBER);}
311 NAME {RETURN(PSI_T_NAME);}
312 NSNAME {RETURN(PSI_T_NSNAME);}
313 QUOTED_STRING {RETURN(PSI_T_QUOTED_STRING);}
314 [^] {break;}
315 */
316 }
317 return -1;
318 }