X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fas3%2Ftokenizer.lex;h=7e936b65cdb3834459d60686269523dbc741b285;hb=c63b2bf21dc1df9a736f0b4c08f6cba828cdab92;hp=805cf2e68ee516da0e3329719f3fc7d1df1356f6;hpb=62a83d162b254d91da418cee25f5b87b067a3f92;p=swftools.git diff --git a/lib/as3/tokenizer.lex b/lib/as3/tokenizer.lex index 805cf2e..7e936b6 100644 --- a/lib/as3/tokenizer.lex +++ b/lib/as3/tokenizer.lex @@ -42,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') { @@ -76,6 +76,9 @@ void as3_buffer_input(void*buffer, int len) 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; \ @@ -107,10 +110,10 @@ void handleInclude(char*text, int len, char quotes) } else { int i1=0,i2=len; // find start - while(!strchr(" \n\r\t", text[i1])) i1++; + while(!strchr(" \n\r\t\xa0", text[i1])) i1++; // strip - while(strchr(" \n\r\t", text[i1])) i1++; - while(strchr(" \n\r\t", text[i2-1])) i2--; + while(strchr(" \n\r\t\xa0", text[i1])) i1++; + while(strchr(" \n\r\t\xa0", text[i2-1])) i2--; if(i2!=len) text[i2]=0; filename = strdup(&text[i1]); } @@ -123,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) @@ -252,6 +255,12 @@ static void handleCData(char*s, int len) a3_lval.str.str = strdup_n(a3_lval.str.str, a3_lval.str.len); } +static void handleRaw(char*s, int len) +{ + 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]=='"') { @@ -276,7 +285,6 @@ static inline int m(int type) return type; } - static char numberbuf[64]; static char*nrbuf() { @@ -462,45 +470,47 @@ 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 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; + 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 + +X1 parsing identifiers with a non unicode lexer is a knightmare we have to skip all possible +X2 combinations of byte order markers or utf8 space chars and i dont quite like the fact that +X3 lex doesnt support proper comments in this section either... +X4 {NAME_HEAD}{NAME_TAIL} -NAME [a-zA-Z_][a-zA-Z0-9_\\]* -_ [^a-zA-Z0-9_\\] +NAME_NOC2EF [a-zA-Z_\x80-\xc1\xc3-\xee\xf0-\xff] +NAME_EF [\xef][a-zA-Z0-9_\\\x80-\xba\xbc-\xff] +NAME_C2 [\xc2][a-zA-Z0-9_\\\x80-\x9f\xa1-\xff] +NAME_EFBB [\xef][\xbb][a-zA-Z0-9_\\\x80-\xbe\xc0-\xff] +NAME_TAIL [a-zA-Z_0-9\\\x80-\xff]* +NAME_HEAD (({NAME_NOC2EF})|({NAME_EF})|({NAME_C2})|({NAME_EFBB})) +NAME {NAME_HEAD}{NAME_TAIL} + +_ [^a-zA-Z0-9_\\\x80-\xff] HEXINT 0x[a-zA-Z0-9]+ HEXFLOAT 0x[a-zA-Z0-9]*\.[a-zA-Z0-9]* @@ -512,9 +522,14 @@ HEXFLOATWITHSIGN [+-]?({HEXFLOAT}) INTWITHSIGN [+-]?({INT}) FLOATWITHSIGN [+-]?({FLOAT}) -CDATA ])*\]*\]\]\> +CDATA ])*\]*\]\]\> +XMLCOMMENT +XML <[^>]+{S}> +XMLID [A-Za-z0-9_\x80-\xff]+([:][A-Za-z0-9_\x80-\xff]+)? +XMLSTRING ["][^"]*["] + STRING ["](\\[\x00-\xff]|[^\\"\n])*["]|['](\\[\x00-\xff]|[^\\'\n])*['] -S [ \n\r\t] +S ([ \n\r\t\xa0]|[\xc2][\xa0]) MULTILINE_COMMENT [/][*]+([*][^/]|[^/*]|[^*][/]|[\x00-\x1f])*[*]+[/] SINGLELINE_COMMENT \/\/[^\n\r]*[\n\r] REGEXP [/]([^/\n]|\\[/])*[/][a-zA-Z]* @@ -526,41 +541,68 @@ REGEXP [/]([^/\n]|\\[/])*[/][a-zA-Z]* [/][*] {syntaxerror("syntax error: unterminated comment", yytext);} ^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;} +^include{S}+[^" \t\xa0\r\n][\x20-\xff]*{S}*/\n {l();handleInclude(yytext, yyleng, 0);} +{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;} +} + +{ +{XMLSTRING} {l(); handleRaw(yytext, yyleng);return T_STRING;} +[{] {c(); BEGIN(REGEXPOK);return m('{');} +[<] {c(); return m('<');} +[/] {c(); return m('/');} +[>] {c(); return m('>');} +[=] {c(); return m('=');} +{XMLID} {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(INITIAL); return m('{');} +[\{] {c(); BEGIN(DEFAULT); return m('{');} -\xef\xbb\xbf {/* utf 8 bom */} +\xef\xbb\xbf {/* utf 8 bom (0xfeff) */} {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();} -NaN {c(); BEGIN(INITIAL);return m(KW_NAN);} +{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();BEGIN(INITIAL);handleLabel(yytext, yyleng-3);return T_FOR;} -{NAME}{S}*:{S}*do/{_} {l();BEGIN(INITIAL);handleLabel(yytext, yyleng-2);return T_DO;} -{NAME}{S}*:{S}*while/{_} {l();BEGIN(INITIAL);handleLabel(yytext, yyleng-5);return T_WHILE;} -{NAME}{S}*:{S}*switch/{_} {l();BEGIN(INITIAL);handleLabel(yytext, yyleng-6);return T_SWITCH;} -for {c();BEGIN(INITIAL);a3_lval.id="";return T_FOR;} -do {c();BEGIN(INITIAL);a3_lval.id="";return T_DO;} -while {c();BEGIN(INITIAL);a3_lval.id="";return T_WHILE;} -switch {c();BEGIN(INITIAL);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;} +default{S}xml {l();BEGIN(DEFAULT);return m(KW_DEFAULT_XML);} +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);} @@ -570,8 +612,8 @@ switch {c();BEGIN(INITIAL);a3_lval.id="";return T_SWITCH;} [=][=] {c();BEGIN(REGEXPOK);return m(T_EQEQ);} [>][=] {c();BEGIN(REGEXPOK);return m(T_GE);} [<][=] {c();BEGIN(REGEXPOK);return m(T_LE);} -[-][-] {c();BEGIN(INITIAL);return m(T_MINUSMINUS);} -[+][+] {c();BEGIN(INITIAL);return m(T_PLUSPLUS);} +[-][-] {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);} @@ -579,6 +621,7 @@ switch {c();BEGIN(INITIAL);a3_lval.id="";return T_SWITCH;} [%][=] {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);} @@ -592,78 +635,62 @@ switch {c();BEGIN(INITIAL);a3_lval.id="";return T_SWITCH;} : {c();BEGIN(REGEXPOK);return m(':');} instanceof {c();BEGIN(REGEXPOK);return m(KW_INSTANCEOF);} implements {c();BEGIN(REGEXPOK);return m(KW_IMPLEMENTS);} -interface {c();BEGIN(INITIAL);return m(KW_INTERFACE);} -namespace {c();BEGIN(INITIAL);return m(KW_NAMESPACE);} -protected {c();BEGIN(INITIAL);return m(KW_PROTECTED);} -undefined {c();BEGIN(INITIAL);return m(KW_UNDEFINED);} -continue {c();BEGIN(INITIAL);return m(KW_CONTINUE);} -override {c();BEGIN(INITIAL);return m(KW_OVERRIDE);} -internal {c();BEGIN(INITIAL);return m(KW_INTERNAL);} -function {c();BEGIN(INITIAL);return m(KW_FUNCTION);} -finally {c();BEGIN(INITIAL);return m(KW_FINALLY);} -default {c();BEGIN(INITIAL);return m(KW_DEFAULT);} -package {c();BEGIN(INITIAL);return m(KW_PACKAGE);} -private {c();BEGIN(INITIAL);return m(KW_PRIVATE);} -dynamic {c();BEGIN(INITIAL);return m(KW_DYNAMIC);} -extends {c();BEGIN(INITIAL);return m(KW_EXTENDS);} +interface {c();BEGIN(DEFAULT);return m(KW_INTERFACE);} +protected {c();BEGIN(DEFAULT);return m(KW_PROTECTED);} +namespace {c();BEGIN(DEFAULT);return m(KW_NAMESPACE);} +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(INITIAL);return m(KW_PUBLIC);} -native {c();BEGIN(INITIAL);return m(KW_NATIVE);} -static {c();BEGIN(INITIAL);return m(KW_STATIC);} +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(INITIAL);return m(KW_CLASS);} -const {c();BEGIN(INITIAL);return m(KW_CONST);} -catch {c();BEGIN(INITIAL);return m(KW_CATCH);} -final {c();BEGIN(INITIAL);return m(KW_FINAL);} -false {c();BEGIN(INITIAL);return m(KW_FALSE);} -break {c();BEGIN(INITIAL);return m(KW_BREAK);} -super {c();BEGIN(INITIAL);return m(KW_SUPER);} -each {c();BEGIN(INITIAL);return m(KW_EACH);} -void {c();BEGIN(INITIAL);return m(KW_VOID);} -true {c();BEGIN(INITIAL);return m(KW_TRUE);} -null {c();BEGIN(INITIAL);return m(KW_NULL);} -else {c();BEGIN(INITIAL);return m(KW_ELSE);} +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(INITIAL);return m(KW_GET);} -set {c();BEGIN(INITIAL);return m(KW_SET);} -var {c();BEGIN(INITIAL);return m(KW_VAR);} -try {c();BEGIN(INITIAL);return m(KW_TRY);} +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(INITIAL);return m(KW_IF) ;} +if {c();BEGIN(DEFAULT);return m(KW_IF) ;} as {c();BEGIN(REGEXPOK);return m(KW_AS);} -$?{NAME} {c();BEGIN(INITIAL);return handleIdentifier();} +$?{NAME} {c();BEGIN(DEFAULT);return handleIdentifier();} -[\]\}*] {c();BEGIN(INITIAL);return m(yytext[0]);} +[\]\}*] {c();BEGIN(DEFAULT);return m(yytext[0]);} [+-\/^~@$!%&\(=\[|?:;,<>] {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(DEFAULT);return m(yytext[0]);} + +{ +. {tokenerror();} +} <> {l(); void*b = leave_file(); if (!b) { @@ -683,6 +710,29 @@ 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 [state=%d]: %s", (yy_start-1)/2, buf); + printf("\n"); + exit(1); + yyterminate(); +} + + static char mbuf[256]; char*token2string(enum yytokentype nr, YYSTYPE v) { @@ -750,6 +800,27 @@ char*token2string(enum yytokentype nr, YYSTYPE v) } } +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);