flush
[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->fp = fp;
34 P->fn = strdup(filename);
35 P->line = 1;
36 P->error = error;
37 P->flags = flags;
38
39 P->proc = PSI_ParserProcAlloc(malloc);
40 if (flags & PSI_PARSER_DEBUG) {
41 PSI_ParserProcTrace(stderr, "PSI> ");
42 }
43
44 PSI_ParserFill(P, 0);
45
46 return P;
47 }
48
49 void PSI_ParserSyntaxError(PSI_Parser *P, const char *fn, size_t ln, const char *msg, ...) {
50 char buf[0x1000] = {0};
51 va_list argv;
52
53 va_start(argv, msg);
54 vsnprintf(buf, 0x1000-1, msg, argv);
55 va_end(argv);
56
57 P->error(PSI_WARNING, "PSI syntax error on line %zu in '%s'%s%s",
58 ln, fn, msg ? ": ": "", buf);
59
60 ++P->errors;
61 }
62
63 size_t PSI_ParserFill(PSI_Parser *P, size_t n)
64 {
65 if (P->flags & PSI_PARSER_DEBUG) {
66 fprintf(stderr, "PSI> Fill: n=%zu\n", n);
67 }
68 if (!n) {
69 P->cur = P->tok = P->lim = P->mrk = P->buf;
70 P->eof = NULL;
71 }
72
73 if (!P->eof) {
74 size_t consumed = P->tok - P->buf;
75 size_t reserved = P->lim - P->tok;
76 size_t available = BSIZE - reserved;
77 size_t didread;
78
79 if (consumed) {
80 memmove(P->buf, P->tok, reserved);
81 P->tok -= consumed;
82 P->cur -= consumed;
83 P->lim -= consumed;
84 P->mrk -= consumed;
85 }
86
87 didread = fread(P->lim, 1, available, P->fp);
88 P->lim += didread;
89 if (didread < available) {
90 P->eof = P->lim;
91 }
92
93 if (P->flags & PSI_PARSER_DEBUG) {
94 fprintf(stderr, "PSI> Fill: consumed=%zu reserved=%zu available=%zu didread=%zu\n",
95 consumed, reserved, available, didread);
96 }
97 }
98 if (P->flags & PSI_PARSER_DEBUG) {
99 fprintf(stderr, "PSI> Fill: avail=%zu\n", P->lim - P->cur);
100 }
101 return P->lim - P->cur;
102 }
103
104 void PSI_ParserParse(PSI_Parser *P, PSI_Token *T)
105 {
106 if (T) {
107 PSI_ParserProc(P->proc, T->type, T, P);
108 } else {
109 PSI_ParserProc(P->proc, 0, NULL, P);
110 }
111 }
112
113 void PSI_ParserDtor(PSI_Parser *P)
114 {
115 PSI_ParserProcFree(P->proc, free);
116
117 if (P->fp) {
118 fclose(P->fp);
119 }
120
121 PSI_DataDtor((PSI_Data *) P);
122
123 memset(P, 0, sizeof(*P));
124 }
125
126 void PSI_ParserFree(PSI_Parser **P)
127 {
128 if (*P) {
129 PSI_ParserDtor(*P);
130 free(*P);
131 *P = NULL;
132 }
133 }
134
135 /*!max:re2c*/
136 #define BSIZE 256
137
138 #if BSIZE < YYMAXFILL
139 # error BSIZE must be greater than YYMAXFILL
140 #endif
141
142 #define RETURN(t) do { \
143 P->num = t; \
144 return t; \
145 } while(1)
146
147 /* DIGIT = [0-9]
148 DIGITS = DIGIT+
149 DECIMALS = (+|-)? DIGIT* "."
150 digits ::= digits DIGIT.
151 decimals ::= digits DOT digits.
152 decimals ::= DOT digits.
153 decimals ::= digits DOT.
154 number ::= digits.
155 number ::= PLUS digits.
156 number ::= MINUS digits.
157 number ::= decimals.
158 number ::= MINUS decimals.
159 number ::= PLUS decimals.
160
161 */
162 token_t PSI_ParserScan(PSI_Parser *P)
163 {
164 for (;;) {
165 P->tok = P->cur;
166 /*!re2c
167 re2c:indent:top = 2;
168 re2c:define:YYCTYPE = "unsigned char";
169 re2c:define:YYCURSOR = P->cur;
170 re2c:define:YYLIMIT = P->lim;
171 re2c:define:YYMARKER = P->mrk;
172 re2c:define:YYFILL = "{ if (!PSI_ParserFill(P,@@)) RETURN(-1); }";
173 re2c:yyfill:parameter = 0;
174
175 B = [^a-zA-Z0-9_];
176 W = [a-zA-Z0-9_];
177 NAME = [a-zA-Z_]W*;
178 NSNAME = (NAME)? ("\\" NAME)+;
179 QUOTED_STRING = "\"" ([^\"])+ "\"";
180 TRUE = 'TRUE';
181 FALSE = 'FALSE';
182 NULL = 'NULL';
183 MIXED = 'mixed';
184 VOID = 'void';
185 BOOL = 'bool';
186 CHAR = 'char';
187 SHORT = 'short';
188 INT = 'int';
189 LONG = 'long';
190 FLOAT = 'float';
191 DOUBLE = 'double';
192 SIZE_T = 'size_t';
193 SINT8 = 'sint8';
194 UINT8 = 'uint8';
195 SINT16 = 'sint16';
196 UINT16 = 'uint16';
197 SINT32 = 'sint32';
198 UINT32 = 'uint32';
199 SINT64 = 'sint64';
200 UINT64 = 'uint64';
201 STRING = 'string';
202 ARRAY = 'array';
203 FUNCTION = 'function';
204 TYPEDEF = 'typedef';
205 STRUCT = 'struct';
206 CONST = 'const';
207 LIB = 'lib';
208 LET = 'let';
209 SET = 'set';
210 RETURN = 'return';
211 FREE = 'free';
212 STRLEN = 'strlen';
213 STRVAL = 'strval';
214 INTVAL = 'intval';
215 FLOATVAL = 'floatval';
216 BOOLVAL = 'boolval';
217 CALLOC = 'calloc';
218 TO_ARRAY = 'to_array';
219 TO_STRING = 'to_string';
220 TO_INT = 'to_int';
221 TO_FLOAT = 'to_float';
222 TO_BOOL = 'to_bool';
223 NUMBER = [+-]? [0-9]* "."? [0-9]+ ([eE] [+-]? [0-9]+)?;
224
225 "#" .* "\n" { ++P->line; RETURN(PSI_T_COMMENT);}
226 "(" {RETURN(PSI_T_LPAREN);}
227 ")" {RETURN(PSI_T_RPAREN);}
228 ";" {RETURN(PSI_T_EOS);}
229 "," {RETURN(PSI_T_COMMA);}
230 ":" {RETURN(PSI_T_COLON);}
231 "{" {RETURN(PSI_T_LBRACE);}
232 "}" {RETURN(PSI_T_RBRACE);}
233 "[" {RETURN(PSI_T_LBRACKET);}
234 "]" {RETURN(PSI_T_RBRACKET);}
235 "=" {RETURN(PSI_T_EQUALS);}
236 "$" {RETURN(PSI_T_DOLLAR);}
237 "*" {RETURN(PSI_T_POINTER);}
238 "&" {RETURN(PSI_T_REFERENCE);}
239 [\r\n] { ++P->line; continue; }
240 [\t ]+ { continue; }
241 TRUE {RETURN(PSI_T_TRUE);}
242 FALSE {RETURN(PSI_T_FALSE);}
243 NULL {RETURN(PSI_T_NULL);}
244 MIXED {RETURN(PSI_T_MIXED);}
245 VOID {RETURN(PSI_T_VOID);}
246 BOOL {RETURN(PSI_T_BOOL);}
247 CHAR {RETURN(PSI_T_CHAR);}
248 SHORT {RETURN(PSI_T_SHORT);}
249 INT {RETURN(PSI_T_INT);}
250 LONG {RETURN(PSI_T_LONG);}
251 FLOAT {RETURN(PSI_T_FLOAT);}
252 DOUBLE {RETURN(PSI_T_DOUBLE);}
253 SIZE_T {RETURN(PSI_T_SIZE_T);}
254 SINT8 {RETURN(PSI_T_SINT8);}
255 UINT8 {RETURN(PSI_T_UINT8);}
256 SINT16 {RETURN(PSI_T_SINT16);}
257 UINT16 {RETURN(PSI_T_UINT16);}
258 SINT32 {RETURN(PSI_T_SINT32);}
259 UINT32 {RETURN(PSI_T_UINT32);}
260 SINT64 {RETURN(PSI_T_SINT64);}
261 UINT64 {RETURN(PSI_T_UINT64);}
262 STRING {RETURN(PSI_T_STRING);}
263 ARRAY {RETURN(PSI_T_ARRAY);}
264 FUNCTION {RETURN(PSI_T_FUNCTION);}
265 TYPEDEF {RETURN(PSI_T_TYPEDEF);}
266 STRUCT {RETURN(PSI_T_STRUCT);}
267 CONST {RETURN(PSI_T_CONST);}
268 LIB {RETURN(PSI_T_LIB);}
269 LET {RETURN(PSI_T_LET);}
270 SET {RETURN(PSI_T_SET);}
271 RETURN {RETURN(PSI_T_RETURN);}
272 FREE {RETURN(PSI_T_FREE);}
273 STRLEN {RETURN(PSI_T_STRLEN);}
274 STRVAL {RETURN(PSI_T_STRVAL);}
275 INTVAL {RETURN(PSI_T_INTVAL);}
276 FLOATVAL {RETURN(PSI_T_FLOATVAL);}
277 BOOLVAL {RETURN(PSI_T_BOOLVAL);}
278 CALLOC {RETURN(PSI_T_CALLOC);}
279 TO_ARRAY {RETURN(PSI_T_TO_ARRAY);}
280 TO_STRING {RETURN(PSI_T_TO_STRING);}
281 TO_INT {RETURN(PSI_T_TO_INT);}
282 TO_FLOAT {RETURN(PSI_T_TO_FLOAT);}
283 TO_BOOL {RETURN(PSI_T_TO_BOOL);}
284 NUMBER {RETURN(PSI_T_NUMBER);}
285 NAME {RETURN(PSI_T_NAME);}
286 NSNAME {RETURN(PSI_T_NSNAME);}
287 QUOTED_STRING {RETURN(PSI_T_QUOTED_STRING);}
288 [^] {break;}
289 */
290 }
291 return -1;
292 }