X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fas3%2Ftokenizer.lex;h=491a5f25af9ddacaae818ab62f0db4ac3fe39c98;hb=639ac6b9f7a89f10d02c5d9ef41bca3bad4eaf2b;hp=63f586dda0e60cbc55ad3cc53ff9690bb32293b1;hpb=063a400cad92488e0cc96f8362a3d54d894e0422;p=swftools.git diff --git a/lib/as3/tokenizer.lex b/lib/as3/tokenizer.lex index 63f586d..491a5f2 100644 --- a/lib/as3/tokenizer.lex +++ b/lib/as3/tokenizer.lex @@ -28,53 +28,12 @@ #include #include #include "../utf8.h" +#include "common.h" #include "tokenizer.h" #include "files.h" -int as3_pass = 0; -int as3_verbosity = 1; unsigned int as3_tokencount = 0; -void as3_error(const char*format, ...) -{ - char buf[1024]; - int l; - va_list arglist; - if(as3_verbosity<0) - exit(1); - va_start(arglist, format); - vsprintf(buf, format, arglist); - va_end(arglist); - fprintf(stderr, "%s:%d:%d: error: %s\n", current_filename_short, current_line, current_column, buf); - fflush(stderr); - exit(1); -} -void as3_warning(const char*format, ...) -{ - char buf[1024]; - int l; - va_list arglist; - if(as3_verbosity<1) - return; - va_start(arglist, format); - vsprintf(buf, format, arglist); - va_end(arglist); - fprintf(stderr, "%s:%d:%d: warning: %s\n", current_filename_short, current_line, current_column, buf); - fflush(stderr); -} -void as3_softwarning(const char*format, ...) -{ - char buf[1024]; - int l; - va_list arglist; - if(as3_verbosity<2) - return; - va_start(arglist, format); - vsprintf(buf, format, arglist); - va_end(arglist); - fprintf(stderr, "%s:%d:%d: warning: %s\n", current_filename_short, current_line, current_column, buf); - fflush(stderr); -} static void dbg(const char*format, ...) { char buf[1024]; @@ -83,7 +42,7 @@ static void dbg(const char*format, ...) if(as3_verbosity<3) return; va_start(arglist, format); - vsprintf(buf, format, arglist); + vsnprintf(buf, sizeof(buf)-1, format, arglist); va_end(arglist); l = strlen(buf); while(l && buf[l-1]=='\n') { @@ -109,12 +68,17 @@ void as3_file_input(FILE*fi) } void as3_buffer_input(void*buffer, int len) { + if(!buffer) + syntaxerror("trying to parse zero bytearray"); as3_buffer = buffer; as3_buffer_len = len; as3_buffer_pos = 0; as3_in = 0; } +//#undef BEGIN +//#define BEGIN(x) {(yy_start) = 1 + 2 *x;dbg("entering state %d", x);} + #define YY_INPUT(buf,result,max_size) { \ if(!as3_buffer) { \ errno=0; \ @@ -154,7 +118,7 @@ void handleInclude(char*text, int len, char quotes) filename = strdup(&text[i1]); } - char*fullfilename = find_file(filename); + char*fullfilename = find_file(filename, 1); enter_file2(filename, fullfilename, YY_CURRENT_BUFFER); yyin = fopen(fullfilename, "rb"); if (!yyin) { @@ -162,7 +126,7 @@ void handleInclude(char*text, int len, char quotes) } yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) ); - //BEGIN(INITIAL); keep context + //BEGIN(DEFAULT); keep context } static int do_unescape(const char*s, const char*end, char*n) @@ -257,8 +221,15 @@ static int do_unescape(const char*s, const char*end, char*n) } break; } - default: - syntaxerror("unknown escape sequence: \"\\%c\"", *s); + default: { + if(o) { + o[len+0] = '\\'; + o[len+1] = *s; + } + s++; + len+=2; + break; + } } } if(o) o[len]=0; @@ -281,16 +252,17 @@ static void handleCData(char*s, int len) { a3_lval.str.str = s+9; // + a3_lval.str.str = strdup_n(a3_lval.str.str, a3_lval.str.len); } -static void handleString(char*s, int len) +static void handleRaw(char*s, int len) { - if(as3_pass < 2) { - // don't bother decoding strings in pass 1 - memset(&a3_lval, 0, sizeof(a3_lval)); - return; - } + a3_lval.str.len = len; + a3_lval.str.str = strdup_n(s, a3_lval.str.len); +} +static void handleString(char*s, int len) +{ if(s[0]=='"') { if(s[len-1]!='"') syntaxerror("String doesn't end with '\"'"); s++;len-=2; @@ -300,7 +272,6 @@ static void handleString(char*s, int len) s++;len-=2; } else syntaxerror("String incorrectly terminated"); - a3_lval.str = string_unescape(s, len); } @@ -308,22 +279,12 @@ static void handleString(char*s, int len) char start_of_expression; -static inline int handleIdentifier(int type) -{ - char*s = malloc(yyleng+1); - memcpy(s, yytext, yyleng); - s[yyleng]=0; - a3_lval.id = s; - return type; -} - static inline int m(int type) { a3_lval.token = type; return type; } - static char numberbuf[64]; static char*nrbuf() { @@ -338,22 +299,7 @@ static char*nrbuf() static inline int setint(int v) { a3_lval.number_int = v; - if(v>-128) - return T_BYTE; - else if(v>=-32768) - return T_SHORT; - else - return T_INT; -} -static inline int setuint(unsigned int v) -{ - a3_lval.number_uint = v; - if(v<128) - return T_BYTE; - else if(v<32768) - return T_SHORT; - else - return T_UINT; + return T_INT; } static inline int setfloat(double v) { @@ -373,16 +319,18 @@ static inline int handleint() char*s = nrbuf(); char l = (yytext[0]=='-'); - char*max = l?"1073741824":"2147483647"; + //char*max = l?"1073741824":"2147483647"; + char*max = l?"2147483648":"2147483647"; + if(yyleng-l>10) { - as3_warning("integer overflow: %s (converted to Number)", s); + as3_softwarning("integer overflow: %s (converted to Number)", s); return handlefloat(); } if(yyleng-l==10) { int t; for(t=0;tmax[t]) { - as3_warning("integer overflow: %s (converted to Number)", s); + as3_softwarning("integer overflow: %s (converted to Number)", s); return handlefloat(); } else if(yytext[l+t]='a' && c<='f') || (c>='A' && c<='F')) v|=(c&0x0f)+9; } - if(l && v>1073741824) { + if(l && v>=0x80000000) { char*s = nrbuf(); - as3_warning("signed integer overflow: %s (converted to Number)", s); + as3_softwarning("integer overflow: %s (converted to Number)", s); return setfloat(v); } - if(!l && v>2147483647) { + if(!l && v>0x7fffffff) { char*s = nrbuf(); - as3_warning("unsigned integer overflow: %s (converted to Number)", s); + as3_softwarning("integer overflow: %s (converted to Number)", s); return setfloat(v); } if(l==3) { return setint(-(int)v); } else { - return setuint(v); + return setint(v); } } @@ -522,15 +470,48 @@ static inline void c() { current_column+=yyleng; } +trie_t*active_namespaces = 0; +/*void tokenizer_register_namespace(const char*id) +{ + trie_put(namespaces, id, 0); +} +void tokenizer_unregister_namespace(const char*id) +{ + trie_remove(namespaces, id); +}*/ +static inline char tokenizer_is_namespace(const char*id) +{ + return trie_contains(active_namespaces, id); +} + +static inline int handleIdentifier() +{ + char*s = malloc(yyleng+1); + memcpy(s, yytext, yyleng); + s[yyleng]=0; + a3_lval.id = s; + if(tokenizer_is_namespace(s)) + return T_NAMESPACE; + else + return T_IDENTIFIER; +} +static int tokenerror(); + + //Boolean {c();return m(KW_BOOLEAN);} //int {c();return m(KW_INT);} //uint {c();return m(KW_UINT);} //Number {c();return m(KW_NUMBER);} +//XMLCOMMENT +//{XMLCOMMENT} %} %s REGEXPOK %s BEGINNING +%s DEFAULT +%x XMLTEXT +%x XML NAME [a-zA-Z_][a-zA-Z0-9_\\]* _ [^a-zA-Z0-9_\\] @@ -538,18 +519,21 @@ _ [^a-zA-Z0-9_\\] HEXINT 0x[a-zA-Z0-9]+ HEXFLOAT 0x[a-zA-Z0-9]*\.[a-zA-Z0-9]* INT [0-9]+ -FLOAT [0-9]+(\.[0-9]*)?|\.[0-9]+ +FLOAT ([0-9]+(\.[0-9]*)?|\.[0-9]+)(e[0-9]+)? HEXWITHSIGN [+-]?({HEXINT}) HEXFLOATWITHSIGN [+-]?({HEXFLOAT}) INTWITHSIGN [+-]?({INT}) FLOATWITHSIGN [+-]?({FLOAT}) -CDATA ])*\]*\]\]\> +CDATA ])*\]*\]\]\> +XMLCOMMENT +XML <[^>]+{S}> + STRING ["](\\[\x00-\xff]|[^\\"\n])*["]|['](\\[\x00-\xff]|[^\\'\n])*['] S [ \n\r\t] MULTILINE_COMMENT [/][*]+([*][^/]|[^/*]|[^*][/]|[\x00-\x1f])*[*]+[/] -SINGLELINE_COMMENT \/\/[^\n]*\n +SINGLELINE_COMMENT \/\/[^\n\r]*[\n\r] REGEXP [/]([^/\n]|\\[/])*[/][a-zA-Z]* %% @@ -560,36 +544,66 @@ REGEXP [/]([^/\n]|\\[/])*[/][a-zA-Z]* ^include{S}+{STRING}{S}*/\n {l();handleInclude(yytext, yyleng, 1);} ^include{S}+[^" \t\r\n][\x20-\xff]*{S}*/\n {l();handleInclude(yytext, yyleng, 0);} -{STRING} {l(); BEGIN(INITIAL);handleString(yytext, yyleng);return T_STRING;} -{CDATA} {l(); BEGIN(INITIAL);handleCData(yytext, yyleng);return T_STRING;} +{STRING} {l(); BEGIN(DEFAULT);handleString(yytext, yyleng);return T_STRING;} +{CDATA} {l(); BEGIN(DEFAULT);handleCData(yytext, yyleng);return T_STRING;} + +{ +{XMLCOMMENT} {l(); BEGIN(DEFAULT);handleRaw(yytext, yyleng);return T_STRING;} +} + +{ +{STRING} {l(); handleString(yytext, yyleng);return T_STRING;} +[{] {c(); BEGIN(REGEXPOK);return m('{');} +[<] {c(); return m('<');} +[/] {c(); return m('/');} +[>] {c(); return m('>');} +[=] {c(); return m('=');} +{NAME} {c(); handleRaw(yytext, yyleng);return T_IDENTIFIER;} +{S} {l();} +<> {syntaxerror("unexpected end of file");} +} + +{ +[^<>{]+ {l(); handleRaw(yytext, yyleng);return T_STRING;} +[{] {c(); BEGIN(REGEXPOK);return m('{');} +[<] {c(); BEGIN(XML);return m('<');} +[>] {c(); return m('>');} +{XMLCOMMENT} {l(); handleRaw(yytext, yyleng);return T_STRING;} +{CDATA} {l(); handleRaw(yytext, yyleng);return T_STRING;} +<> {syntaxerror("unexpected end of file");} +} { -{REGEXP} {c(); BEGIN(INITIAL);return handleregexp();} -{HEXWITHSIGN} {c(); BEGIN(INITIAL);return handlehex();} -{HEXFLOATWITHSIGN} {c(); BEGIN(INITIAL);return handlehexfloat();} -{INTWITHSIGN} {c(); BEGIN(INITIAL);return handleint();} -{FLOATWITHSIGN} {c(); BEGIN(INITIAL);return handlefloat();} +{REGEXP} {c(); BEGIN(DEFAULT);return handleregexp();} +{HEXWITHSIGN}/{_} {c(); BEGIN(DEFAULT);return handlehex();} +{HEXFLOATWITHSIGN}/{_} {c(); BEGIN(DEFAULT);return handlehexfloat();} +{INTWITHSIGN}/{_} {c(); BEGIN(DEFAULT);return handleint();} +{FLOATWITHSIGN}/{_} {c(); BEGIN(DEFAULT);return handlefloat();} } +[\{] {c(); BEGIN(REGEXPOK);return m(T_DICTSTART);} +[\{] {c(); BEGIN(DEFAULT); return m('{');} + \xef\xbb\xbf {/* utf 8 bom */} {S} {l();} -{HEXINT} {c(); BEGIN(INITIAL);return handlehex();} -{HEXFLOAT} {c(); BEGIN(INITIAL);return handlehexfloat();} -{INT} {c(); BEGIN(INITIAL);return handleint();} -{FLOAT} {c(); BEGIN(INITIAL);return handlefloat();} +{HEXINT}/{_} {c(); BEGIN(DEFAULT);return handlehex();} +{HEXFLOAT}/{_} {c(); BEGIN(DEFAULT);return handlehexfloat();} +{INT}/{_} {c(); BEGIN(DEFAULT);return handleint();} +{FLOAT}/{_} {c(); BEGIN(DEFAULT);return handlefloat();} +NaN {c(); BEGIN(DEFAULT);return m(KW_NAN);} 3rr0r {/* for debugging: generates a tokenizer-level error */ syntaxerror("3rr0r");} -{NAME}{S}*:{S}*for/{_} {l();handleLabel(yytext, yyleng-3);return T_FOR;} -{NAME}{S}*:{S}*do/{_} {l();handleLabel(yytext, yyleng-2);return T_DO;} -{NAME}{S}*:{S}*while/{_} {l();handleLabel(yytext, yyleng-5);return T_WHILE;} -{NAME}{S}*:{S}*switch/{_} {l();handleLabel(yytext, yyleng-6);return T_SWITCH;} -for {c();a3_lval.id="";return T_FOR;} -do {c();a3_lval.id="";return T_DO;} -while {c();a3_lval.id="";return T_WHILE;} -switch {c();a3_lval.id="";return T_SWITCH;} +{NAME}{S}*:{S}*for/{_} {l();BEGIN(DEFAULT);handleLabel(yytext, yyleng-3);return T_FOR;} +{NAME}{S}*:{S}*do/{_} {l();BEGIN(DEFAULT);handleLabel(yytext, yyleng-2);return T_DO;} +{NAME}{S}*:{S}*while/{_} {l();BEGIN(DEFAULT);handleLabel(yytext, yyleng-5);return T_WHILE;} +{NAME}{S}*:{S}*switch/{_} {l();BEGIN(DEFAULT);handleLabel(yytext, yyleng-6);return T_SWITCH;} +for {c();BEGIN(DEFAULT);a3_lval.id="";return T_FOR;} +do {c();BEGIN(DEFAULT);a3_lval.id="";return T_DO;} +while {c();BEGIN(DEFAULT);a3_lval.id="";return T_WHILE;} +switch {c();BEGIN(DEFAULT);a3_lval.id="";return T_SWITCH;} [&][&] {c();BEGIN(REGEXPOK);return m(T_ANDAND);} [|][|] {c();BEGIN(REGEXPOK);return m(T_OROR);} @@ -597,100 +611,87 @@ switch {c();a3_lval.id="";return T_SWITCH;} [!][=][=] {c();BEGIN(REGEXPOK);return m(T_NEE);} [=][=][=] {c();BEGIN(REGEXPOK);return m(T_EQEQEQ);} [=][=] {c();BEGIN(REGEXPOK);return m(T_EQEQ);} -[>][=] {c();return m(T_GE);} -[<][=] {c();return m(T_LE);} -[-][-] {c();BEGIN(INITIAL);return m(T_MINUSMINUS);} -[+][+] {c();BEGIN(INITIAL);return m(T_PLUSPLUS);} -[+][=] {c();return m(T_PLUSBY);} -[-][=] {c();return m(T_MINUSBY);} -[/][=] {c();return m(T_DIVBY);} -[%][=] {c();return m(T_MODBY);} -[*][=] {c();return m(T_MULBY);} -[|][=] {c();return m(T_ORBY);} -[>][>][=] {c();return m(T_SHRBY);} -[<][<][=] {c();return m(T_SHLBY);} -[>][>][>][=] {c();return m(T_USHRBY);} -[<][<] {c();return m(T_SHL);} -[>][>][>] {c();return m(T_USHR);} -[>][>] {c();return m(T_SHR);} -\.\.\. {c();return m(T_DOTDOTDOT);} -\.\. {c();return m(T_DOTDOT);} -\. {c();return m('.');} -:: {c();return m(T_COLONCOLON);} -: {c();return m(':');} -instanceof {c();return m(KW_INSTANCEOF);} -implements {c();return m(KW_IMPLEMENTS);} -interface {c();return m(KW_INTERFACE);} -namespace {c();return m(KW_NAMESPACE);} -protected {c();return m(KW_PROTECTED);} -undefined {c();return m(KW_UNDEFINED);} -continue {c();return m(KW_CONTINUE);} -override {c();return m(KW_OVERRIDE);} -internal {c();return m(KW_INTERNAL);} -function {c();return m(KW_FUNCTION);} -finally {c();return m(KW_FINALLY);} -default {c();return m(KW_DEFAULT);} -package {c();return m(KW_PACKAGE);} -private {c();return m(KW_PRIVATE);} -dynamic {c();return m(KW_DYNAMIC);} -extends {c();return m(KW_EXTENDS);} -delete {c();return m(KW_DELETE);} -return {c();return m(KW_RETURN);} -public {c();return m(KW_PUBLIC);} -native {c();return m(KW_NATIVE);} -static {c();return m(KW_STATIC);} -import {c();return m(KW_IMPORT);} -typeof {c();return m(KW_TYPEOF);} -throw {c();return m(KW_THROW);} -class {c();return m(KW_CLASS);} -const {c();return m(KW_CONST);} -catch {c();return m(KW_CATCH);} -final {c();return m(KW_FINAL);} -false {c();return m(KW_FALSE);} -break {c();return m(KW_BREAK);} -super {c();return m(KW_SUPER);} -each {c();return m(KW_EACH);} -void {c();return m(KW_VOID);} -true {c();return m(KW_TRUE);} -null {c();return m(KW_NULL);} -else {c();return m(KW_ELSE);} -case {c();return m(KW_CASE);} -with {c();return m(KW_WITH);} -use {c();return m(KW_USE);} -new {c();return m(KW_NEW);} -get {c();return m(KW_GET);} -set {c();return m(KW_SET);} -var {c();return m(KW_VAR);} -try {c();return m(KW_TRY);} -is {c();return m(KW_IS) ;} -in {c();return m(KW_IN) ;} -if {c();return m(KW_IF) ;} -as {c();return m(KW_AS);} -{NAME} {c();BEGIN(INITIAL);return handleIdentifier(T_IDENTIFIER);} - -[+-\/*^~@$!%&\(=\[\]\{\}|?:;,<>] {c();BEGIN(REGEXPOK);return m(yytext[0]);} -[\)\]] {c();BEGIN(INITIAL);return m(yytext[0]);} - -. {/* ERROR */ - char c1=yytext[0]; - char buf[128]; - buf[0] = yytext[0]; - int t; - for(t=1;t<128;t++) { - char c = buf[t]=input(); - if(c=='\n' || c==EOF) { - buf[t] = 0; - break; - } - } - if(c1>='0' && c1<='9') - syntaxerror("syntax error: %s (identifiers must not start with a digit)"); - else - syntaxerror("syntax error: %s", buf); - printf("\n"); - exit(1); - yyterminate(); - } +[>][=] {c();BEGIN(REGEXPOK);return m(T_GE);} +[<][=] {c();BEGIN(REGEXPOK);return m(T_LE);} +[-][-] {c();BEGIN(DEFAULT);return m(T_MINUSMINUS);} +[+][+] {c();BEGIN(DEFAULT);return m(T_PLUSPLUS);} +[+][=] {c();BEGIN(REGEXPOK);return m(T_PLUSBY);} +[\^][=] {c();BEGIN(REGEXPOK);return m(T_XORBY);} +[-][=] {c();BEGIN(REGEXPOK);return m(T_MINUSBY);} +[/][=] {c();BEGIN(REGEXPOK);return m(T_DIVBY);} +[%][=] {c();BEGIN(REGEXPOK);return m(T_MODBY);} +[*][=] {c();BEGIN(REGEXPOK);return m(T_MULBY);} +[|][=] {c();BEGIN(REGEXPOK);return m(T_ORBY);} +[&][=] {c();BEGIN(REGEXPOK);return m(T_ANDBY);} +[>][>][=] {c();BEGIN(REGEXPOK);return m(T_SHRBY);} +[<][<][=] {c();BEGIN(REGEXPOK);return m(T_SHLBY);} +[>][>][>][=] {c();BEGIN(REGEXPOK);return m(T_USHRBY);} +[<][<] {c();BEGIN(REGEXPOK);return m(T_SHL);} +[>][>][>] {c();BEGIN(REGEXPOK);return m(T_USHR);} +[>][>] {c();BEGIN(REGEXPOK);return m(T_SHR);} +\.\.\. {c();BEGIN(REGEXPOK);return m(T_DOTDOTDOT);} +\.\. {c();BEGIN(REGEXPOK);return m(T_DOTDOT);} +\. {c();BEGIN(REGEXPOK);return m('.');} +:: {c();BEGIN(REGEXPOK);return m(T_COLONCOLON);} +: {c();BEGIN(REGEXPOK);return m(':');} +instanceof {c();BEGIN(REGEXPOK);return m(KW_INSTANCEOF);} +implements {c();BEGIN(REGEXPOK);return m(KW_IMPLEMENTS);} +interface {c();BEGIN(DEFAULT);return m(KW_INTERFACE);} +namespace {c();BEGIN(DEFAULT);return m(KW_NAMESPACE);} +protected {c();BEGIN(DEFAULT);return m(KW_PROTECTED);} +undefined {c();BEGIN(DEFAULT);return m(KW_UNDEFINED);} +arguments {c();BEGIN(DEFAULT);return m(KW_ARGUMENTS);} +continue {c();BEGIN(DEFAULT);return m(KW_CONTINUE);} +override {c();BEGIN(DEFAULT);return m(KW_OVERRIDE);} +internal {c();BEGIN(DEFAULT);return m(KW_INTERNAL);} +function {c();BEGIN(DEFAULT);return m(KW_FUNCTION);} +finally {c();BEGIN(DEFAULT);return m(KW_FINALLY);} +default {c();BEGIN(DEFAULT);return m(KW_DEFAULT);} +package {c();BEGIN(DEFAULT);return m(KW_PACKAGE);} +private {c();BEGIN(DEFAULT);return m(KW_PRIVATE);} +dynamic {c();BEGIN(DEFAULT);return m(KW_DYNAMIC);} +extends {c();BEGIN(DEFAULT);return m(KW_EXTENDS);} +delete {c();BEGIN(REGEXPOK);return m(KW_DELETE);} +return {c();BEGIN(REGEXPOK);return m(KW_RETURN);} +public {c();BEGIN(DEFAULT);return m(KW_PUBLIC);} +native {c();BEGIN(DEFAULT);return m(KW_NATIVE);} +static {c();BEGIN(DEFAULT);return m(KW_STATIC);} +import {c();BEGIN(REGEXPOK);return m(KW_IMPORT);} +typeof {c();BEGIN(REGEXPOK);return m(KW_TYPEOF);} +throw {c();BEGIN(REGEXPOK);return m(KW_THROW);} +class {c();BEGIN(DEFAULT);return m(KW_CLASS);} +const {c();BEGIN(DEFAULT);return m(KW_CONST);} +catch {c();BEGIN(DEFAULT);return m(KW_CATCH);} +final {c();BEGIN(DEFAULT);return m(KW_FINAL);} +false {c();BEGIN(DEFAULT);return m(KW_FALSE);} +break {c();BEGIN(DEFAULT);return m(KW_BREAK);} +super {c();BEGIN(DEFAULT);return m(KW_SUPER);} +each {c();BEGIN(DEFAULT);return m(KW_EACH);} +void {c();BEGIN(DEFAULT);return m(KW_VOID);} +true {c();BEGIN(DEFAULT);return m(KW_TRUE);} +null {c();BEGIN(DEFAULT);return m(KW_NULL);} +else {c();BEGIN(DEFAULT);return m(KW_ELSE);} +case {c();BEGIN(REGEXPOK);return m(KW_CASE);} +with {c();BEGIN(REGEXPOK);return m(KW_WITH);} +use {c();BEGIN(REGEXPOK);return m(KW_USE);} +new {c();BEGIN(REGEXPOK);return m(KW_NEW);} +get {c();BEGIN(DEFAULT);return m(KW_GET);} +set {c();BEGIN(DEFAULT);return m(KW_SET);} +var {c();BEGIN(DEFAULT);return m(KW_VAR);} +try {c();BEGIN(DEFAULT);return m(KW_TRY);} +is {c();BEGIN(REGEXPOK);return m(KW_IS) ;} +in {c();BEGIN(REGEXPOK);return m(KW_IN) ;} +if {c();BEGIN(DEFAULT);return m(KW_IF) ;} +as {c();BEGIN(REGEXPOK);return m(KW_AS);} +$?{NAME} {c();BEGIN(DEFAULT);return handleIdentifier();} + +[\]\}*] {c();BEGIN(DEFAULT);return m(yytext[0]);} +[+-\/^~@$!%&\(=\[|?:;,<>] {c();BEGIN(REGEXPOK);return m(yytext[0]);} +[\)\]] {c();BEGIN(DEFAULT);return m(yytext[0]);} + +{ +. {tokenerror();} +} <> {l(); void*b = leave_file(); if (!b) { @@ -710,15 +711,52 @@ int yywrap() return 1; } +static int tokenerror() +{ + char c1=yytext[0]; + char buf[128]; + buf[0] = yytext[0]; + int t; + for(t=1;t<128;t++) { + char c = buf[t]=input(); + if(c=='\n' || c==EOF) { + buf[t] = 0; + break; + } + } + if(c1>='0' && c1<='9') + syntaxerror("syntax error: %s (identifiers must not start with a digit)"); + else + syntaxerror("syntax error [%d]: %s", (yy_start-1)/2, buf); + printf("\n"); + exit(1); + yyterminate(); +} + + static char mbuf[256]; char*token2string(enum yytokentype nr, YYSTYPE v) { - if(nr==T_STRING) return ""; + if(nr==T_STRING) { + char*s = malloc(v.str.len+10); + strcpy(s, ""); + memcpy(s+8, v.str.str, v.str.len); + sprintf(s+8+v.str.len, " (%d bytes)", v.str.len); + return s; + } + else if(nr==T_REGEXP) { + char*s = malloc(strlen(v.regexp.pattern)+10); + sprintf(s, "%s", v.regexp.pattern); + return s; + } + else if(nr==T_IDENTIFIER) { + char*s = malloc(strlen(v.id)+10); + sprintf(s, "%s", v.id); + return s; + } else if(nr==T_INT) return ""; else if(nr==T_UINT) return ""; - else if(nr==T_BYTE) return ""; else if(nr==T_FLOAT) return ""; - else if(nr==T_REGEXP) return "REGEXP"; else if(nr==T_EOF) return "***END***"; else if(nr==T_GE) return ">="; else if(nr==T_LE) return "<="; @@ -757,13 +795,33 @@ char*token2string(enum yytokentype nr, YYSTYPE v) else if(nr==KW_VAR) return "var"; else if(nr==KW_IS) return "is"; else if(nr==KW_AS) return "as"; - else if(nr==T_IDENTIFIER) return "ID"; else { sprintf(mbuf, "%d", nr); return mbuf; } } +void tokenizer_begin_xml() +{ + dbg("begin reading xml"); + BEGIN(XML); +} +void tokenizer_begin_xmltext() +{ + dbg("begin reading xml text"); + BEGIN(XMLTEXT); +} +void tokenizer_end_xmltext() +{ + dbg("end reading xml text"); + BEGIN(XML); +} +void tokenizer_end_xml() +{ + dbg("end reading xml"); + BEGIN(DEFAULT); +} + void initialize_scanner() { BEGIN(BEGINNING);