10 static void countlines(char*text, int len) {
22 static int verbose = 1;
23 static void dbg(const char*format, ...)
30 va_start(arglist, format);
31 vsprintf(buf, format, arglist);
34 while(l && buf[l-1]=='\n') {
38 printf("(tokenizer) ");
43 void syntaxerror(const char*format, ...)
50 va_start(arglist, format);
51 vsprintf(buf, format, arglist);
53 fprintf(stderr, "%s:%d:%d: error: %s\n", current_filename, current_line, current_column, buf);
59 #ifndef YY_CURRENT_BUFFER
60 #define YY_CURRENT_BUFFER yy_current_buffer
63 void handleInclude(char*text, int len, char quotes)
67 char*p1 = strchr(text, '"');
68 char*p2 = strrchr(text, '"');
69 if(!p1 || !p2 || p1==p2) {
70 syntaxerror("Invalid include in line %d\n", current_line);
73 filename = strdup(p1+1);
77 while(!strchr(" \n\r\t", text[i1])) i1++;
79 while(strchr(" \n\r\t", text[i1])) i1++;
80 while(strchr(" \n\r\t", text[i2-1])) i2--;
81 if(i2!=len) text[i2]=0;
82 filename = strdup(&text[i1]);
85 char*fullfilename = enter_file(filename, YY_CURRENT_BUFFER);
86 yyin = fopen(fullfilename, "rb");
88 syntaxerror("Couldn't open include file \"%s\"\n", fullfilename);
91 yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) );
92 //BEGIN(INITIAL); keep context
95 char start_of_expression;
97 static inline int m(int type)
99 char*s = malloc(yyleng+1);
100 memcpy(s, yytext, yyleng);
110 static char numberbuf[64];
111 static inline int handlenumber()
113 if(yyleng>sizeof(numberbuf)-1)
114 syntaxerror("decimal number overflow");
117 memcpy(s, yytext, yyleng);
122 for(t=0;t<yyleng;t++) {
126 if(!strchr("0123456789", yytext[t])) {
127 syntaxerror("Invalid number");
131 avm2_lval.number_float = atof(s);
138 char*max = l?"2147483648":"4294967296";
140 syntaxerror("integer overflow");
143 for(t=0;t<yyleng-l;t++) {
144 if(yytext[l+t]>max[t])
145 syntaxerror("integer overflow");
146 else if(yytext[l+t]<max[t])
151 avm2_lval.number_int = atoi(s);
154 unsigned int v = atoi(s);
155 avm2_lval.number_uint = v;
158 else if(v<0x80000000)
165 void initialize_scanner();
166 #define YY_USER_INIT initialize_scanner();
168 #define c() {countlines(yytext, yyleng);}
175 NAME [a-zA-Z_][a-zA-Z0-9_\\]*
177 NUMBER -?[0-9]+(\.[0-9]*)?
179 STRING ["](\\[\x00-\xff]|[^\\"\n])*["]|['](\\[\x00-\xff]|[^\\'\n])*[']
181 MULTILINE_COMMENT [/][*]([*][^/]|[^*]|[\x00-\x31])*[*]+[/]
182 SINGLELINE_COMMENT \/\/[^\n]*\n
183 REGEXP [/]([^/\n]|\\[/])*[/][a-zA-Z]*
187 {SINGLELINE_COMMENT} {c(); /* single line comment */}
188 {MULTILINE_COMMENT} {c(); /* multi line comment */}
189 [/][*] {syntaxerror("syntax error: unterminated comment", yytext);}
191 ^include{S}+{STRING}{S}*/\n {c();handleInclude(yytext, yyleng, 1);}
192 ^include{S}+[^" \t\r\n][\x20-\xff]*{S}*/\n {c();handleInclude(yytext, yyleng, 0);}
193 {STRING} {c(); BEGIN(INITIAL);return m(T_STRING);}
195 <BEGINNING,REGEXPOK>{
196 {REGEXP} {c(); BEGIN(INITIAL);return m(T_REGEXP);}
199 \xef\xbb\xbf {/* utf 8 bom */}
202 {NUMBER} {c(); BEGIN(INITIAL);return handlenumber();}
204 [>][=] {return m(T_GE);}
205 [<][=] {return m(T_LE);}
206 [-][-] {BEGIN(INITIAL);return m(T_MINUSMINUS);}
207 [+][+] {BEGIN(INITIAL);return m(T_PLUSPLUS);}
208 == {BEGIN(REGEXPOK);return m(T_EQEQ);}
209 \.\. {return m(T_DOTDOT);}
211 :: {return m(T_COLONCOLON);}
213 implements {return m(KW_IMPLEMENTS);}
214 interface {return m(KW_INTERFACE);}
215 namespace {return m(KW_NAMESPACE);}
216 protected {return m(KW_PROTECTED);}
217 override {return m(KW_OVERRIDE);}
218 internal {return m(KW_INTERNAL);}
219 function {return m(KW_FUNCTION);}
220 package {return m(KW_PACKAGE);}
221 private {return m(KW_PRIVATE);}
222 Boolean {return m(KW_BOOLEAN);}
223 dynamic {return m(KW_DYNAMIC);}
224 extends {return m(KW_EXTENDS);}
225 public {return m(KW_PUBLIC);}
226 native {return m(KW_NATIVE);}
227 static {return m(KW_STATIC);}
228 import {return m(KW_IMPORT);}
229 Number {return m(KW_NUMBER);}
230 class {return m(KW_CLASS);}
231 const {return m(KW_CONST);}
232 final {return m(KW_FINAL);}
233 False {return m(KW_FALSE);}
234 True {return m(KW_TRUE);}
235 uint {return m(KW_UINT);}
236 null {return m(KW_NULL);}
237 use {return m(KW_USE);}
238 int {return m(KW_INT);}
239 new {return m(KW_NEW);}
240 get {return m(KW_GET);}
241 for {return m(KW_FOR);}
242 set {return m(KW_SET);}
243 var {return m(KW_VAR);}
244 is {return m(KW_IS) ;}
245 as {return m(KW_AS);}
246 {NAME} {c();BEGIN(INITIAL);return m(T_IDENTIFIER);}
248 [+-\/*^~@$!%&\(=\[\]\{\}|?:;,.<>] {c();BEGIN(REGEXPOK);return m(yytext[0]);}
249 [\)\]] {c();BEGIN(INITIAL);return m(yytext[0]);}
251 . {char c1=yytext[0];
256 char c = buf[t]=input();
257 if(c=='\n' || c==EOF) {
262 if(c1>='0' && c1<='9')
263 syntaxerror("syntax error: %s (identifiers must not start with a digit)");
265 syntaxerror("syntax error: %s", buf);
271 void*b = leave_file();
274 yy_delete_buffer(YY_CURRENT_BUFFER);
277 yy_delete_buffer(YY_CURRENT_BUFFER);
278 yy_switch_to_buffer(b);
289 static char mbuf[256];
290 char*token2string(token_t*t)
293 if(nr==T_STRING) return "<string>";
294 else if(nr==T_INT) return "<int>";
295 else if(nr==T_UINT) return "<uint>";
296 else if(nr==T_FLOAT) return "<float>";
297 else if(nr==T_REGEXP) return "REGEXP";
298 else if(nr==T_EOF) return "***END***";
299 else if(nr==T_GE) return ">=";
300 else if(nr==T_LE) return "<=";
301 else if(nr==T_MINUSMINUS) return "--";
302 else if(nr==T_PLUSPLUS) return "++";
303 else if(nr==KW_IMPLEMENTS) return "implements";
304 else if(nr==KW_INTERFACE) return "interface";
305 else if(nr==KW_NAMESPACE) return "namespace";
306 else if(nr==KW_PROTECTED) return "protected";
307 else if(nr==KW_OVERRIDE) return "override";
308 else if(nr==KW_INTERNAL) return "internal";
309 else if(nr==KW_FUNCTION) return "function";
310 else if(nr==KW_PACKAGE) return "package";
311 else if(nr==KW_PRIVATE) return "private";
312 else if(nr==KW_BOOLEAN) return "Boolean";
313 else if(nr==KW_DYNAMIC) return "dynamic";
314 else if(nr==KW_EXTENDS) return "extends";
315 else if(nr==KW_PUBLIC) return "public";
316 else if(nr==KW_NATIVE) return "native";
317 else if(nr==KW_STATIC) return "static";
318 else if(nr==KW_IMPORT) return "import";
319 else if(nr==KW_NUMBER) return "number";
320 else if(nr==KW_CLASS) return "class";
321 else if(nr==KW_CONST) return "const";
322 else if(nr==KW_FINAL) return "final";
323 else if(nr==KW_FALSE) return "False";
324 else if(nr==KW_TRUE) return "True";
325 else if(nr==KW_UINT) return "uint";
326 else if(nr==KW_NULL) return "null";
327 else if(nr==KW_USE) return "use";
328 else if(nr==KW_INT) return "int";
329 else if(nr==KW_NEW) return "new";
330 else if(nr==KW_GET) return "get";
331 else if(nr==KW_FOR) return "for";
332 else if(nr==KW_SET) return "set";
333 else if(nr==KW_VAR) return "var";
334 else if(nr==KW_IS) return "is";
335 else if(nr==KW_AS) return "as";
336 else if(nr==T_IDENTIFIER) {
337 if(strlen(t->text)>sizeof(mbuf)-1)
339 sprintf(mbuf, "ID(%s)", t->text);
342 sprintf(mbuf, "%d", nr);
347 void initialize_scanner()