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++) {
125 syntaxerror("Invalid number");
127 } else if(!strchr("-0123456789", yytext[t])) {
128 syntaxerror("Invalid number");
132 avm2_lval.number_float = atof(s);
135 char l = (yytext[0]=='-');
137 char*max = l?"1073741824":"2147483647";
139 syntaxerror("integer overflow");
142 for(t=0;t<yyleng-l;t++) {
143 if(yytext[l+t]>max[t])
144 syntaxerror("integer overflow %s > %s", s+l,max);
145 else if(yytext[l+t]<max[t])
151 avm2_lval.number_int = v;
160 for(t=0;t<yyleng;t++) {
164 avm2_lval.number_uint = v;
174 void initialize_scanner();
175 #define YY_USER_INIT initialize_scanner();
177 #define c() {countlines(yytext, yyleng);}
184 NAME [a-zA-Z_][a-zA-Z0-9_\\]*
186 NUMBER -?[0-9]+(\.[0-9]*)?
188 STRING ["](\\[\x00-\xff]|[^\\"\n])*["]|['](\\[\x00-\xff]|[^\\'\n])*[']
190 MULTILINE_COMMENT [/][*]([*][^/]|[^*]|[\x00-\x31])*[*]+[/]
191 SINGLELINE_COMMENT \/\/[^\n]*\n
192 REGEXP [/]([^/\n]|\\[/])*[/][a-zA-Z]*
196 {SINGLELINE_COMMENT} {c(); /* single line comment */}
197 {MULTILINE_COMMENT} {c(); /* multi line comment */}
198 [/][*] {syntaxerror("syntax error: unterminated comment", yytext);}
200 ^include{S}+{STRING}{S}*/\n {c();handleInclude(yytext, yyleng, 1);}
201 ^include{S}+[^" \t\r\n][\x20-\xff]*{S}*/\n {c();handleInclude(yytext, yyleng, 0);}
202 {STRING} {c(); BEGIN(INITIAL);return m(T_STRING);}
204 <BEGINNING,REGEXPOK>{
205 {REGEXP} {c(); BEGIN(INITIAL);return m(T_REGEXP);}
208 \xef\xbb\xbf {/* utf 8 bom */}
211 {NUMBER} {c(); BEGIN(INITIAL);return handlenumber();}
213 [>][=] {return m(T_GE);}
214 [<][=] {return m(T_LE);}
215 [-][-] {BEGIN(INITIAL);return m(T_MINUSMINUS);}
216 [+][+] {BEGIN(INITIAL);return m(T_PLUSPLUS);}
217 == {BEGIN(REGEXPOK);return m(T_EQEQ);}
218 \.\. {return m(T_DOTDOT);}
220 :: {return m(T_COLONCOLON);}
222 implements {return m(KW_IMPLEMENTS);}
223 interface {return m(KW_INTERFACE);}
224 namespace {return m(KW_NAMESPACE);}
225 protected {return m(KW_PROTECTED);}
226 override {return m(KW_OVERRIDE);}
227 internal {return m(KW_INTERNAL);}
228 function {return m(KW_FUNCTION);}
229 package {return m(KW_PACKAGE);}
230 private {return m(KW_PRIVATE);}
231 Boolean {return m(KW_BOOLEAN);}
232 dynamic {return m(KW_DYNAMIC);}
233 extends {return m(KW_EXTENDS);}
234 public {return m(KW_PUBLIC);}
235 native {return m(KW_NATIVE);}
236 static {return m(KW_STATIC);}
237 import {return m(KW_IMPORT);}
238 Number {return m(KW_NUMBER);}
239 class {return m(KW_CLASS);}
240 const {return m(KW_CONST);}
241 final {return m(KW_FINAL);}
242 False {return m(KW_FALSE);}
243 True {return m(KW_TRUE);}
244 uint {return m(KW_UINT);}
245 null {return m(KW_NULL);}
246 use {return m(KW_USE);}
247 int {return m(KW_INT);}
248 new {return m(KW_NEW);}
249 get {return m(KW_GET);}
250 for {return m(KW_FOR);}
251 set {return m(KW_SET);}
252 var {return m(KW_VAR);}
253 is {return m(KW_IS) ;}
254 as {return m(KW_AS);}
255 {NAME} {c();BEGIN(INITIAL);return m(T_IDENTIFIER);}
257 [+-\/*^~@$!%&\(=\[\]\{\}|?:;,.<>] {c();BEGIN(REGEXPOK);return m(yytext[0]);}
258 [\)\]] {c();BEGIN(INITIAL);return m(yytext[0]);}
260 . {char c1=yytext[0];
265 char c = buf[t]=input();
266 if(c=='\n' || c==EOF) {
271 if(c1>='0' && c1<='9')
272 syntaxerror("syntax error: %s (identifiers must not start with a digit)");
274 syntaxerror("syntax error: %s", buf);
280 void*b = leave_file();
283 yy_delete_buffer(YY_CURRENT_BUFFER);
286 yy_delete_buffer(YY_CURRENT_BUFFER);
287 yy_switch_to_buffer(b);
298 static char mbuf[256];
299 char*token2string(token_t*t)
302 if(nr==T_STRING) return "<string>";
303 else if(nr==T_INT) return "<int>";
304 else if(nr==T_UINT) return "<uint>";
305 else if(nr==T_FLOAT) return "<float>";
306 else if(nr==T_REGEXP) return "REGEXP";
307 else if(nr==T_EOF) return "***END***";
308 else if(nr==T_GE) return ">=";
309 else if(nr==T_LE) return "<=";
310 else if(nr==T_MINUSMINUS) return "--";
311 else if(nr==T_PLUSPLUS) return "++";
312 else if(nr==KW_IMPLEMENTS) return "implements";
313 else if(nr==KW_INTERFACE) return "interface";
314 else if(nr==KW_NAMESPACE) return "namespace";
315 else if(nr==KW_PROTECTED) return "protected";
316 else if(nr==KW_OVERRIDE) return "override";
317 else if(nr==KW_INTERNAL) return "internal";
318 else if(nr==KW_FUNCTION) return "function";
319 else if(nr==KW_PACKAGE) return "package";
320 else if(nr==KW_PRIVATE) return "private";
321 else if(nr==KW_BOOLEAN) return "Boolean";
322 else if(nr==KW_DYNAMIC) return "dynamic";
323 else if(nr==KW_EXTENDS) return "extends";
324 else if(nr==KW_PUBLIC) return "public";
325 else if(nr==KW_NATIVE) return "native";
326 else if(nr==KW_STATIC) return "static";
327 else if(nr==KW_IMPORT) return "import";
328 else if(nr==KW_NUMBER) return "number";
329 else if(nr==KW_CLASS) return "class";
330 else if(nr==KW_CONST) return "const";
331 else if(nr==KW_FINAL) return "final";
332 else if(nr==KW_FALSE) return "False";
333 else if(nr==KW_TRUE) return "True";
334 else if(nr==KW_UINT) return "uint";
335 else if(nr==KW_NULL) return "null";
336 else if(nr==KW_USE) return "use";
337 else if(nr==KW_INT) return "int";
338 else if(nr==KW_NEW) return "new";
339 else if(nr==KW_GET) return "get";
340 else if(nr==KW_FOR) return "for";
341 else if(nr==KW_SET) return "set";
342 else if(nr==KW_VAR) return "var";
343 else if(nr==KW_IS) return "is";
344 else if(nr==KW_AS) return "as";
345 else if(nr==T_IDENTIFIER) {
346 if(strlen(t->text)>sizeof(mbuf)-1)
348 sprintf(mbuf, "ID(%s)", t->text);
351 sprintf(mbuf, "%d", nr);
356 void initialize_scanner()