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