From 90d975d69cf53eb970cc30bb5e91e5c5d58d6292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Thu, 29 May 2025 09:14:15 +0200 Subject: [PATCH] AS3 highlighter. Refactoring of highligter. --- CHANGELOG.md | 6 +- .../lexers/actionscript3_script.flex | 344 +- .../abc/avm2/parser/AVM2ParseException.java | 11 + .../parser/script/ActionScript3Parser.java | 12 +- .../script/ActionScript3SimpleParser.java | 3137 +++++++++++++++++ .../avm2/parser/script/ActionScriptLexer.java | 360 +- .../abc/avm2/parser/script/ParsedSymbol.java | 13 +- ...er.java => ActionScript2SimpleParser.java} | 271 +- .../CatchScope.java | 2 +- .../ClassScope.java | 2 +- .../FunctionScope.java | 2 +- .../variables => simpleparser}/Scope.java | 2 +- .../SimpleParseException.java} | 10 +- .../flash/simpleparser/SimpleParser.java | 46 + .../variables => simpleparser}/Type.java | 2 +- .../variables => simpleparser}/Variable.java | 2 +- .../VariableOrScope.java | 2 +- .../decompiler/flash/gui/abc/ABCPanel.java | 28 +- .../flash/gui/abc/DecompiledEditorPane.java | 21 +- .../flash/gui/action/ActionPanel.java | 7 +- .../gui/editor/DebuggableEditorPane.java | 9 - .../gui/editor/LineMarkedEditorPane.java | 14 +- .../VariableMarker.java} | 45 +- 23 files changed, 3780 insertions(+), 568 deletions(-) create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java rename libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/{variables/ActionScript2VariableParser.java => ActionScript2SimpleParser.java} (85%) rename libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/{action/parser/script/variables => simpleparser}/CatchScope.java (95%) rename libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/{action/parser/script/variables => simpleparser}/ClassScope.java (94%) rename libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/{action/parser/script/variables => simpleparser}/FunctionScope.java (94%) rename libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/{action/parser/script/variables => simpleparser}/Scope.java (93%) rename libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/{action/parser/script/variables/ActionVariableParseException.java => simpleparser/SimpleParseException.java} (79%) create mode 100644 libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParser.java rename libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/{action/parser/script/variables => simpleparser}/Type.java (92%) rename libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/{action/parser/script/variables => simpleparser}/Variable.java (94%) rename libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/{action/parser/script/variables => simpleparser}/VariableOrScope.java (91%) rename src/com/jpexs/decompiler/flash/gui/{action/ActionVariableMarker.java => editor/VariableMarker.java} (89%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 739ef8255..35a75537b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,10 +18,10 @@ All notable changes to this project will be documented in this file. - "Show detail" context menu item for items in folder preview - [#1682] AS2 - Adding class by context menu on packages - Simple editor - detection of english color name (based on CSS names) -- AS1/2 - highlight variable definition and all its instances on cursor place +- AS1/2/3 - highlight variable definition and all its instances on cursor place (also in edit mode) -- AS1/2 - underline errors in the code (also in edit mode) -- AS1/2 - highlight variables and errors on scrollbar +- AS1/2/3 - underline errors in the code (also in edit mode) +- AS1/2/3 - highlight variables and errors on scrollbar ### Changed - AS1/2 - Single DoAction tag inside frame is now displayed directly as frame node diff --git a/libsrc/ffdec_lib/lexers/actionscript3_script.flex b/libsrc/ffdec_lib/lexers/actionscript3_script.flex index 28999a4c9..6b1c5664c 100644 --- a/libsrc/ffdec_lib/lexers/actionscript3_script.flex +++ b/libsrc/ffdec_lib/lexers/actionscript3_script.flex @@ -81,6 +81,8 @@ import com.jpexs.decompiler.flash.abc.types.Float4; private static String xmlTagName = ""; + private int startPos = -1; + public int yychar() { return yychar; } @@ -249,144 +251,147 @@ RegExp = \/([^\r\n/]|\\\/)+\/[a-z]* { /* keywords */ - "break" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.BREAK, yytext()); } - "case" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CASE, yytext()); } - "continue" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CONTINUE, yytext()); } - "default" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.DEFAULT, yytext()); } - "do" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.DO, yytext()); } - "while" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.WHILE, yytext()); } - "else" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.ELSE, yytext()); } - "for" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FOR, yytext()); } - "each" { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.EACH, yytext()); } - "in" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IN, yytext()); } - "if" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IF, yytext()); } - "return" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.RETURN, yytext()); } - "super" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.SUPER, yytext()); } - "switch" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.SWITCH, yytext()); } - "throw" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.THROW, yytext()); } - "try" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.TRY, yytext()); } - "catch" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CATCH, yytext()); } - "finally" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FINALLY, yytext()); } - "while" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.WHILE, yytext()); } - "with" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.WITH, yytext()); } - "dynamic" { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.DYNAMIC, yytext()); } - "internal" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.INTERNAL, yytext()); } - "override" { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.OVERRIDE, yytext()); } - "private" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PRIVATE, yytext()); } - "protected" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PROTECTED, yytext()); } - "public" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PUBLIC, yytext()); } - "static" { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.STATIC, yytext()); } - "class" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CLASS, yytext()); } - "const" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CONST, yytext()); } - "extends" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.EXTENDS, yytext()); } - "function" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FUNCTION, yytext()); } - "get" { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.GET, yytext()); } - "implements" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IMPLEMENTS, yytext()); } - "interface" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.INTERFACE, yytext()); } - "namespace" { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.NAMESPACE, yytext()); } - "package" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PACKAGE, yytext()); } - "set" { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.SET, yytext()); } - "var" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.VAR, yytext()); } - "import" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IMPORT, yytext()); } - "use" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.USE, yytext()); } - "false" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FALSE, yytext()); } - "null" { return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.NULL, yytext()); } - "this" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.THIS, yytext()); } - "true" { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.TRUE, yytext()); } - "undefined" { return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.UNDEFINED, yytext()); } - "Infinity" { return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.INFINITY, yytext()); } - "NaN" { return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.NAN, yytext()); } - "final" { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.FINAL, yytext()); } - "native" { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.NATIVE, yytext()); } + "break" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.BREAK, yytext()); } + "case" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.CASE, yytext()); } + "continue" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.CONTINUE, yytext()); } + "default" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.DEFAULT, yytext()); } + "do" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.DO, yytext()); } + "while" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.WHILE, yytext()); } + "else" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.ELSE, yytext()); } + "for" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.FOR, yytext()); } + "each" { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.EACH, yytext()); } + "in" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.IN, yytext()); } + "if" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.IF, yytext()); } + "return" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.RETURN, yytext()); } + "super" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.SUPER, yytext()); } + "switch" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.SWITCH, yytext()); } + "throw" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.THROW, yytext()); } + "try" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.TRY, yytext()); } + "catch" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.CATCH, yytext()); } + "finally" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.FINALLY, yytext()); } + "while" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.WHILE, yytext()); } + "with" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.WITH, yytext()); } + "dynamic" { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.DYNAMIC, yytext()); } + "internal" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.INTERNAL, yytext()); } + "override" { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.OVERRIDE, yytext()); } + "private" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.PRIVATE, yytext()); } + "protected" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.PROTECTED, yytext()); } + "public" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.PUBLIC, yytext()); } + "static" { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.STATIC, yytext()); } + "class" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.CLASS, yytext()); } + "const" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.CONST, yytext()); } + "extends" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.EXTENDS, yytext()); } + "function" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.FUNCTION, yytext()); } + "get" { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.GET, yytext()); } + "implements" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.IMPLEMENTS, yytext()); } + "interface" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.INTERFACE, yytext()); } + "namespace" { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.NAMESPACE, yytext()); } + "package" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.PACKAGE, yytext()); } + "set" { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.SET, yytext()); } + "var" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.VAR, yytext()); } + "import" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.IMPORT, yytext()); } + "use" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.USE, yytext()); } + "false" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.FALSE, yytext()); } + "null" { return new ParsedSymbol(yychar(), SymbolGroup.GLOBALCONST, SymbolType.NULL, yytext()); } + "this" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.THIS, yytext()); } + "true" { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.TRUE, yytext()); } + "undefined" { return new ParsedSymbol(yychar(), SymbolGroup.GLOBALCONST, SymbolType.UNDEFINED, yytext()); } + "Infinity" { return new ParsedSymbol(yychar(), SymbolGroup.GLOBALCONST, SymbolType.INFINITY, yytext()); } + "NaN" { return new ParsedSymbol(yychar(), SymbolGroup.GLOBALCONST, SymbolType.NAN, yytext()); } + "final" { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.FINAL, yytext()); } + "native" { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.NATIVE, yytext()); } {VerbatimString} { String verbatimString = yytext(); verbatimString = verbatimString.substring(2, verbatimString.length() - 1); - return new ParsedSymbol(SymbolGroup.STRING, SymbolType.STRING, verbatimString); } + return new ParsedSymbol(yychar(), SymbolGroup.STRING, SymbolType.STRING, verbatimString); } /* operators */ - "(" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.PARENT_OPEN, yytext()); } - ")" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.PARENT_CLOSE, yytext()); } - "{" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.CURLY_OPEN, yytext()); } - "}" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.CURLY_CLOSE, yytext()); } - "[" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BRACKET_OPEN, yytext()); } - "]" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BRACKET_CLOSE, yytext()); } - ";" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.SEMICOLON, yytext()); } - "," { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.COMMA, yytext()); } - "..." { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.REST, yytext()); } - "." { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DOT, yytext()); } - "=" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN, yytext()); } - ">" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.GREATER_THAN, yytext()); } - "<" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.LOWER_THAN, yytext()); } - "!" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NOT, yytext()); } - "~" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NEGATE, yytext()); } - "?." { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NULL_DOT, yytext()); } - "??" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NULL_COALESCE, yytext()); } - "?" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.TERNAR, yytext()); } - ":" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.COLON, yytext()); } - "===" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.STRICT_EQUALS, yytext()); } - "==" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.EQUALS, yytext()); } - "<=" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.LOWER_EQUAL, yytext()); } - ">=" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.GREATER_EQUAL, yytext()); } - "!==" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.STRICT_NOT_EQUAL, yytext()); } - "!=" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NOT_EQUAL, yytext()); } - "&&=" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_AND, yytext()); } - "&&" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.AND, yytext()); } - "||=" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_OR, yytext()); } - "||" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.OR, yytext()); } - "++" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.INCREMENT, yytext()); } - "--" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DECREMENT, yytext()); } - "+" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.PLUS, yytext()); } - "-" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.MINUS, yytext()); } - "*" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.MULTIPLY, yytext()); } - "/" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DIVIDE, yytext()); } - "&" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BITAND, yytext()); } - "|" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BITOR, yytext()); } - "^" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.XOR, yytext()); } - "%" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.MODULO, yytext()); } - "<<" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.SHIFT_LEFT, yytext()); } - ">>" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.SHIFT_RIGHT, yytext()); } - ">>>" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.USHIFT_RIGHT, yytext()); } - "+=" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_PLUS, yytext()); } - "-=" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_MINUS, yytext()); } - "*=" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_MULTIPLY, yytext()); } - "/=" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_DIVIDE, yytext()); } - "&=" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_BITAND, yytext()); } - "|=" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_BITOR, yytext()); } - "^=" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_XOR, yytext()); } - "%=" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_MODULO, yytext()); } - "<<=" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_SHIFT_LEFT, yytext()); } - ">>=" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_SHIFT_RIGHT, yytext()); } - ">>>=" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_USHIFT_RIGHT, yytext()); } - "as" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.AS, yytext()); } - "delete" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DELETE, yytext()); } - "instanceof" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.INSTANCEOF, yytext()); } - "is" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.IS, yytext()); } - "::" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NAMESPACE_OP, yytext()); } - "new" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NEW, yytext()); } - "typeof" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.TYPEOF, yytext()); } - "void" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.VOID, yytext()); } - "@" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ATTRIBUTE, yytext()); } - ".(" { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.FILTER, yytext()); } - ".." { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DESCENDANTS, yytext()); } + "(" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.PARENT_OPEN, yytext()); } + ")" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.PARENT_CLOSE, yytext()); } + "{" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.CURLY_OPEN, yytext()); } + "}" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.CURLY_CLOSE, yytext()); } + "[" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.BRACKET_OPEN, yytext()); } + "]" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.BRACKET_CLOSE, yytext()); } + ";" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.SEMICOLON, yytext()); } + "," { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.COMMA, yytext()); } + "..." { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.REST, yytext()); } + "." { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.DOT, yytext()); } + "=" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN, yytext()); } + ">" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.GREATER_THAN, yytext()); } + "<" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.LOWER_THAN, yytext()); } + "!" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.NOT, yytext()); } + "~" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.NEGATE, yytext()); } + "?." { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.NULL_DOT, yytext()); } + "??" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.NULL_COALESCE, yytext()); } + "?" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.TERNAR, yytext()); } + ":" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.COLON, yytext()); } + "===" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.STRICT_EQUALS, yytext()); } + "==" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.EQUALS, yytext()); } + "<=" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.LOWER_EQUAL, yytext()); } + ">=" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.GREATER_EQUAL, yytext()); } + "!==" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.STRICT_NOT_EQUAL, yytext()); } + "!=" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.NOT_EQUAL, yytext()); } + "&&=" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_AND, yytext()); } + "&&" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.AND, yytext()); } + "||=" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_OR, yytext()); } + "||" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.OR, yytext()); } + "++" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.INCREMENT, yytext()); } + "--" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.DECREMENT, yytext()); } + "+" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.PLUS, yytext()); } + "-" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.MINUS, yytext()); } + "*" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.MULTIPLY, yytext()); } + "/" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.DIVIDE, yytext()); } + "&" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.BITAND, yytext()); } + "|" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.BITOR, yytext()); } + "^" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.XOR, yytext()); } + "%" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.MODULO, yytext()); } + "<<" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.SHIFT_LEFT, yytext()); } + ">>" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.SHIFT_RIGHT, yytext()); } + ">>>" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.USHIFT_RIGHT, yytext()); } + "+=" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_PLUS, yytext()); } + "-=" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_MINUS, yytext()); } + "*=" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_MULTIPLY, yytext()); } + "/=" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_DIVIDE, yytext()); } + "&=" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_BITAND, yytext()); } + "|=" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_BITOR, yytext()); } + "^=" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_XOR, yytext()); } + "%=" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_MODULO, yytext()); } + "<<=" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_SHIFT_LEFT, yytext()); } + ">>=" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_SHIFT_RIGHT, yytext()); } + ">>>=" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_USHIFT_RIGHT, yytext()); } + "as" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.AS, yytext()); } + "delete" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.DELETE, yytext()); } + "instanceof" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.INSTANCEOF, yytext()); } + "is" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.IS, yytext()); } + "::" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.NAMESPACE_OP, yytext()); } + "new" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.NEW, yytext()); } + "typeof" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.TYPEOF, yytext()); } + "void" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.VOID, yytext()); } + "@" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ATTRIBUTE, yytext()); } + ".(" { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.FILTER, yytext()); } + ".." { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.DESCENDANTS, yytext()); } /* string literal */ \" { + startPos = yychar(); string.setLength(0); yybegin(STRING); } {Preprocessor} { - return new ParsedSymbol(SymbolGroup.PREPROCESSOR, SymbolType.PREPROCESSOR, yytext().substring(2)); + return new ParsedSymbol(yychar(), SymbolGroup.PREPROCESSOR, SymbolType.PREPROCESSOR, yytext().substring(2)); } "\u00A7" { + startPos = yychar(); string.setLength(0); yybegin(OIDENTIFIER); } /* character literal */ \' { + startPos = yychar(); string.setLength(0); yybegin(CHARLITERAL); } @@ -399,50 +404,50 @@ RegExp = \/([^\r\n/]|\\\/)+\/[a-z]* ival = ival.substring(0, ival.length() - 1); } try{ - return new ParsedSymbol(SymbolGroup.INTEGER, SymbolType.INTEGER, Integer.parseInt(ival)); + return new ParsedSymbol(yychar(), SymbolGroup.INTEGER, SymbolType.INTEGER, Integer.parseInt(ival)); } catch(NumberFormatException nfe){ //its too long for an Integer var - return new ParsedSymbol(SymbolGroup.DOUBLE, SymbolType.DOUBLE, Double.parseDouble(ival)); + return new ParsedSymbol(yychar(), SymbolGroup.DOUBLE, SymbolType.DOUBLE, Double.parseDouble(ival)); } } {HexIntegerLiteral} { try { - return new ParsedSymbol(SymbolGroup.INTEGER, SymbolType.INTEGER, Integer.parseInt(yytext().substring(2), 16)); + return new ParsedSymbol(yychar(), SymbolGroup.INTEGER, SymbolType.INTEGER, Integer.parseInt(yytext().substring(2), 16)); } catch (NumberFormatException nfe) { //its too long for an Integer var - return new ParsedSymbol(SymbolGroup.DOUBLE, SymbolType.DOUBLE, new BigInteger(yytext().substring(2), 16).doubleValue()); + return new ParsedSymbol(yychar(), SymbolGroup.DOUBLE, SymbolType.DOUBLE, new BigInteger(yytext().substring(2), 16).doubleValue()); } } {OctIntegerLiteral} { try { - return new ParsedSymbol(SymbolGroup.INTEGER, SymbolType.INTEGER, Integer.parseInt(yytext(), 8)); + return new ParsedSymbol(yychar(), SymbolGroup.INTEGER, SymbolType.INTEGER, Integer.parseInt(yytext(), 8)); } catch (NumberFormatException nfe) { //its too long for an Integer var - return new ParsedSymbol(SymbolGroup.DOUBLE, SymbolType.DOUBLE, new BigInteger(yytext(), 8).doubleValue()); + return new ParsedSymbol(yychar(), SymbolGroup.DOUBLE, SymbolType.DOUBLE, new BigInteger(yytext(), 8).doubleValue()); } } {DoubleLiteral} { String dval = yytext(); if (dval.endsWith("m")) { dval = dval.substring(0, dval.length() - 1); - return new ParsedSymbol(SymbolGroup.DECIMAL, SymbolType.DECIMAL, new Decimal128(dval)); + return new ParsedSymbol(yychar(), SymbolGroup.DECIMAL, SymbolType.DECIMAL, new Decimal128(dval)); } if (dval.endsWith("f")) { dval = dval.substring(0, dval.length() - 1); - return new ParsedSymbol(SymbolGroup.FLOAT, SymbolType.FLOAT, Float.parseFloat(dval)); + return new ParsedSymbol(yychar(), SymbolGroup.FLOAT, SymbolType.FLOAT, Float.parseFloat(dval)); } if (dval.endsWith("d")) { dval = dval.substring(0, dval.length() - 1); } - return new ParsedSymbol(SymbolGroup.DOUBLE, SymbolType.DOUBLE, Double.parseDouble(dval)); + return new ParsedSymbol(yychar(), SymbolGroup.DOUBLE, SymbolType.DOUBLE, Double.parseDouble(dval)); } {FloatLiteral} { String fval = yytext(); if (fval.endsWith("f")) { fval = fval.substring(0, fval.length() - 1); } - return new ParsedSymbol(SymbolGroup.FLOAT, SymbolType.FLOAT, Float.parseFloat(fval)); + return new ParsedSymbol(yychar(), SymbolGroup.FLOAT, SymbolType.FLOAT, Float.parseFloat(fval)); } {Float4Literal} { @@ -456,22 +461,23 @@ RegExp = \/([^\r\n/]|\\\/)+\/[a-z]* } fvalues[i] = Float.parseFloat(fval); } - return new ParsedSymbol(SymbolGroup.FLOAT4, SymbolType.FLOAT4, new Float4(fvalues)); + return new ParsedSymbol(yychar(), SymbolGroup.FLOAT4, SymbolType.FLOAT4, new Float4(fvalues)); } /* comments */ {Comment} { yyline += count(yytext(),"\n"); } {LineTerminator} { yyline++; - if (enableWhiteSpace) { return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_WHITESPACE, yytext()); } + if (enableWhiteSpace) { return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_WHITESPACE, yytext()); } } /* whitespace */ - {WhiteSpace} { if (enableWhiteSpace) { return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_WHITESPACE, yytext()); } } - {TypeNameSpec} { return new ParsedSymbol(SymbolGroup.TYPENAME, SymbolType.TYPENAME, yytext()); } + {WhiteSpace} { if (enableWhiteSpace) { return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_WHITESPACE, yytext()); } } + {TypeNameSpec} { return new ParsedSymbol(yychar(), SymbolGroup.TYPENAME, SymbolType.TYPENAME, yytext()); } {XmlOpenTagStart} { + startPos = yychar(); yybegin(XMLOPENTAG); string.setLength(0); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTTAG_BEGIN, yytext()); + return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_STARTTAG_BEGIN, yytext()); } {XmlCommentStart} { string.setLength(0); string.append(yytext() ); yybegin(XMLCOMMENTALONE); @@ -479,20 +485,20 @@ RegExp = \/([^\r\n/]|\\\/)+\/[a-z]* {XmlCDataStart} { string.setLength(0); string.append(yytext() ); yybegin(XMLCDATAALONE); } - "<{" { return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTVARTAG_BEGIN, yytext()); } + "<{" { return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_STARTVARTAG_BEGIN, yytext()); } /* identifiers */ - {Identifier} { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, yytext()); } + {Identifier} { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, yytext()); } /* regexp */ - {RegExp} { return new ParsedSymbol(SymbolGroup.REGEXP, SymbolType.REGEXP, yytext()); } - {NamespaceSuffix} { return new ParsedSymbol(SymbolGroup.NAMESPACESUFFIX, SymbolType.NAMESPACESUFFIX, Integer.parseInt(yytext().substring(1))); } + {RegExp} { return new ParsedSymbol(yychar(), SymbolGroup.REGEXP, SymbolType.REGEXP, yytext()); } + {NamespaceSuffix} { return new ParsedSymbol(yychar(), SymbolGroup.NAMESPACESUFFIX, SymbolType.NAMESPACESUFFIX, Integer.parseInt(yytext().substring(1))); } } { ">" { yybegin(XML); - pushback(new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.GREATER_THAN, yytext())); + pushback(new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.GREATER_THAN, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); @@ -505,36 +511,36 @@ RegExp = \/([^\r\n/]|\\\/)+\/[a-z]* { {XmlAttribute} { yybegin(XMLOPENTAGATTRIB); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRIBUTENAME, yytext())); + pushback(new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_ATTRIBUTENAME, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); } "{" { yybegin(YYINITIAL); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRNAMEVAR_BEGIN, yytext())); + pushback(new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_ATTRNAMEVAR_BEGIN, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); } {XmlOpenTagEnd} { yybegin(XML); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTTAG_END, yytext())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_STARTTAG_END, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); } {XmlOpenTagClose} { yybegin(XML); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTFINISHTAG_END, yytext())); + pushback(new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_STARTFINISHTAG_END, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); @@ -548,15 +554,15 @@ RegExp = \/([^\r\n/]|\\\/)+\/[a-z]* { \"{XmlDQuoteStringChar}*\" { yybegin(XMLOPENTAG); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRIBUTEVALUE, yytext()); + return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_ATTRIBUTEVALUE, yytext()); } \'{XmlSQuoteStringChar}*\' { yybegin(XMLOPENTAG); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRIBUTEVALUE_SINGLEQUOTED, yytext()); + return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_ATTRIBUTEVALUE_SINGLEQUOTED, yytext()); } "{" { yybegin(YYINITIAL); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRVALVAR_BEGIN, yytext()); + return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_ATTRVALVAR_BEGIN, yytext()); } } @@ -567,7 +573,7 @@ RegExp = \/([^\r\n/]|\\\/)+\/[a-z]* string.append(yytext()); String tos = string.toString(); string.setLength(0); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_INSTR, tos); + return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_INSTR, tos); } {LineTerminator} { string.append(yytext()); yyline++;} [^] { string.append(yytext()); } @@ -579,7 +585,7 @@ RegExp = \/([^\r\n/]|\\\/)+\/[a-z]* yybegin(XML); String ret = string.toString(); string.setLength(0); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_CDATA, ret); + return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_CDATA, ret); } {LineTerminator} { string.append(yytext()); yyline++;} [^] { string.append(yytext()); } @@ -591,7 +597,7 @@ RegExp = \/([^\r\n/]|\\\/)+\/[a-z]* yybegin(YYINITIAL); String ret = string.toString(); string.setLength(0); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_CDATA, ret); + return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_CDATA, ret); } {LineTerminator} { string.append(yytext()); yyline++;} [^] { string.append(yytext()); } @@ -603,7 +609,7 @@ RegExp = \/([^\r\n/]|\\\/)+\/[a-z]* yybegin(XML); String ret = string.toString(); string.setLength(0); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_COMMENT, ret); + return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_COMMENT, ret); } {LineTerminator} { string.append(yytext()); yyline++;} [^] { string.append(yytext());} @@ -615,7 +621,7 @@ RegExp = \/([^\r\n/]|\\\/)+\/[a-z]* yybegin(YYINITIAL); String ret = string.toString(); string.setLength(0); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_COMMENT, ret); + return new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_COMMENT, ret); } {LineTerminator} { string.append(yytext()); yyline++;} [^] { string.append(yytext());} @@ -624,7 +630,7 @@ RegExp = \/([^\r\n/]|\\\/)+\/[a-z]* { {XmlCDataStart} { String ret = string.toString(); string.setLength(0); string.append(yytext() ); yybegin(XMLCDATA); - if (!ret.isEmpty()) return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, ret); + if (!ret.isEmpty()) return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_TEXT, ret); } {XmlInstrStart} { yybegin(XMLINSTR); @@ -632,27 +638,27 @@ RegExp = \/([^\r\n/]|\\\/)+\/[a-z]* String tos = string.toString(); string.setLength(0); string.append(yytext()); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, tos); + return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_TEXT, tos); } string.append(yytext()); } {XmlCommentStart} { String ret = string.toString(); string.setLength(0); string.append(yytext()); yybegin(XMLCOMMENT); - if (!ret.isEmpty()) return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, ret); + if (!ret.isEmpty()) return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_TEXT, ret); } {XmlOpenTagStart} { yybegin(XMLOPENTAG); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTTAG_BEGIN, yytext())); + pushback(new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_STARTTAG_BEGIN, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); } {XmlCloseTag} { - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_FINISHTAG, yytext())); + pushback(new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_FINISHTAG, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); @@ -660,27 +666,27 @@ RegExp = \/([^\r\n/]|\\\/)+\/[a-z]* "<{" { yybegin(YYINITIAL); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTVARTAG_BEGIN, yytext())); + pushback(new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_STARTVARTAG_BEGIN, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); } " 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); } "{" { yybegin(YYINITIAL); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_VAR_BEGIN, yytext())); + pushback(new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_VAR_BEGIN, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); @@ -694,7 +700,7 @@ RegExp = \/([^\r\n/]|\\\/)+\/[a-z]* yybegin(YYINITIAL); repeatNum = 1; // length also includes the trailing quote - return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, string.toString()); + return new ParsedSymbol(startPos, SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, string.toString()); } {OIdentifierCharacter} { for(int r=0;r> { return new ParsedSymbol(SymbolGroup.EOF, SymbolType.EOF, null); } +<> { return new ParsedSymbol(yychar(), SymbolGroup.EOF, SymbolType.EOF, null); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/AVM2ParseException.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/AVM2ParseException.java index bd2ee8ca9..e80063766 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/AVM2ParseException.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/AVM2ParseException.java @@ -34,4 +34,15 @@ public class AVM2ParseException extends ParseException { public AVM2ParseException(String text, long line) { super(text, line); } + + /** + * Constructor. + * + * @param text Text + * @param line Line + * @param position Position + */ + public AVM2ParseException(String text, long line, long position) { + super(text, line, position); + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java index ece06d4a1..63c8e2054 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java @@ -266,12 +266,12 @@ public class ActionScript3Parser { s = lex(); } while (s.type == SymbolType.COMMA); if (s.type == SymbolType.USHIFT_RIGHT) { - s = new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.GREATER_THAN); + s = new ParsedSymbol(-1, SymbolGroup.OPERATOR, SymbolType.GREATER_THAN); lexer.pushback(s); lexer.pushback(s); } if (s.type == SymbolType.SHIFT_RIGHT) { - s = new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.GREATER_THAN); + s = new ParsedSymbol(-1, SymbolGroup.OPERATOR, SymbolType.GREATER_THAN); lexer.pushback(s); } expected(s, lexer.yyline(), SymbolType.GREATER_THAN); @@ -442,8 +442,8 @@ public class ActionScript3Parser { if (s.type == SymbolType.BRACKET_OPEN) { lexer.pushback(s); if (attrBracket) { - lexer.pushback(new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ATTRIBUTE, "@")); - lexer.pushback(new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DOT, ".")); + lexer.pushback(new ParsedSymbol(-1, SymbolGroup.OPERATOR, SymbolType.ATTRIBUTE, "@")); + lexer.pushback(new ParsedSymbol(-1, SymbolGroup.OPERATOR, SymbolType.DOT, ".")); } ret = member(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables, abc); } else { @@ -2609,7 +2609,7 @@ public class ActionScript3Parser { if (!abc.hasFloat4Support()) { //parse again as method call lexer.yypushbackstr(lexer.yytext().substring("float4".length())); - lexer.pushback(new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, "float4")); + lexer.pushback(new ParsedSymbol(-1, SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, "float4")); ret = name(allOpenedNamespaces, thisType, pkg, needsActivation, false, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses, abc); } else { ret = new Float4ValueAVM2Item(null, null, (Float4) s.value); @@ -2653,7 +2653,7 @@ public class ActionScript3Parser { s = lex(); if (s.type == SymbolType.XML_STARTTAG_BEGIN) { lexer.yypushbackstr(s.value.toString().substring(1), ActionScriptLexer.YYINITIAL); - s = new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.LOWER_THAN); + s = new ParsedSymbol(-1, SymbolGroup.OPERATOR, SymbolType.LOWER_THAN); } if (s.type == SymbolType.FUNCTION) { s = lexer.lex(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java new file mode 100644 index 000000000..c8bddb149 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java @@ -0,0 +1,3137 @@ +/* + * Copyright (C) 2010-2025 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc.avm2.parser.script; + +import com.jpexs.decompiler.flash.abc.avm2.parser.script.*; +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.NumberContext; +import com.jpexs.decompiler.flash.abc.avm2.graph.AVM2GraphTargetDialect; +import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.StringAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.operations.AddAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException; +import com.jpexs.decompiler.flash.abc.types.Namespace; +import com.jpexs.decompiler.flash.simpleparser.SimpleParseException; +import com.jpexs.decompiler.flash.simpleparser.CatchScope; +import com.jpexs.decompiler.flash.simpleparser.ClassScope; +import com.jpexs.decompiler.flash.simpleparser.FunctionScope; +import com.jpexs.decompiler.flash.simpleparser.Scope; +import com.jpexs.decompiler.flash.simpleparser.SimpleParser; +import com.jpexs.decompiler.flash.simpleparser.Type; +import com.jpexs.decompiler.flash.simpleparser.Variable; +import com.jpexs.decompiler.flash.simpleparser.VariableOrScope; +import com.jpexs.decompiler.graph.CompilationException; +import com.jpexs.decompiler.graph.DottedChain; +import com.jpexs.decompiler.graph.GraphTargetDialect; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.Loop; +import com.jpexs.decompiler.graph.TypeItem; +import com.jpexs.helpers.CancellableWorker; +import com.jpexs.helpers.Reference; +import java.io.IOException; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * ActionScript 3 parser. + * + * @author JPEXS + */ +public class ActionScript3SimpleParser implements SimpleParser { + + private static final GraphTargetDialect DIALECT = AVM2GraphTargetDialect.INSTANCE; + + private long uniqLast = 0; + + private final boolean debugMode = false; + + private static final String AS3_NAMESPACE = "http://adobe.com/AS3/2006/builtin"; + private final ABC abc; + +// private final AbcIndexing abcIndex; + + private long uniqId() { + uniqLast++; + return uniqLast; + } + + private void commands(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, List variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + if (debugMode) { + System.out.println("commands:"); + } + while (command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables, abc)) { + } + if (debugMode) { + System.out.println("/commands"); + } + } + + private boolean type(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, List variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + ParsedSymbol s = lex(); + if (s.type == SymbolType.MULTIPLY) { + //return TypeItem.UNBOUNDED; + variables.add(new Type(false, "*", s.position)); + return true; + } else if (s.type == SymbolType.VOID) { + //return new TypeItem(DottedChain.VOID); + variables.add(new Type(false, "void", s.position)); + return true; + } else { + lexer.pushback(s); + } + + //GraphTargetItem t = ; + boolean t = name(allOpenedNamespaces, thisType, pkg, needsActivation, true, openedNamespaces, null, false, false, variables, importedClasses, abc); + //t = + applyType(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, t, new HashMap<>(), false, false, variables, abc); + //return t; + return true; + } + + private boolean memberOrCall(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean newcmds, HashMap registerVars, boolean inFunction, boolean inMethod, List variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + if (debugMode) { + System.out.println("memberOrCall:"); + } + ParsedSymbol s = lex(); + boolean ret = newcmds; + while (s.isType(SymbolType.DOT, SymbolType.NULL_DOT, SymbolType.PARENT_OPEN, SymbolType.BRACKET_OPEN, SymbolType.TYPENAME, SymbolType.FILTER, SymbolType.DESCENDANTS)) { + switch (s.type) { + case BRACKET_OPEN: + case DOT: + case NULL_DOT: + case TYPENAME: + lexer.pushback(s); + ret = member(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables, abc); + break; + case FILTER: + needsActivation.setVal(true); + //ret = new XMLFilterAVM2Item(ret,; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, inMethod, variables, true, abc); + //, openedNamespaces); + expectedType(SymbolType.PARENT_CLOSE); + ret = true; + break; + case PARENT_OPEN: + //ret = new CallAVM2Item(openedNamespaces, lexer.yyline(), ret,; + call(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables, abc); + //, abcIndex); + ret = true; + break; + case DESCENDANTS: + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.MULTIPLY); + //ret = new GetDescendantsAVM2Item(ret, s.type == SymbolType.MULTIPLY ? null : s.value.toString(), openedNamespaces); + ret = true; + break; + + } + s = lex(); + } + if (s.type == SymbolType.INCREMENT) { + if (!ret) { + //!isNameOrProp(ret) + throw new AVM2ParseException("Invalid assignment", lexer.yyline(), s.position); + } + //ret = new PostIncrementAVM2Item(null, null, ret); + ret = true; + s = lex(); + + } else if (s.type == SymbolType.DECREMENT) { + if (!ret) { + //(!isNameOrProp(ret)) { + throw new AVM2ParseException("Invalid assignment", lexer.yyline(), s.position); + } + //ret = new PostDecrementAVM2Item(null, null, ret); + ret = true; + s = lex(); + } + + lexer.pushback(s); + + if (debugMode) { + System.out.println("/memberOrCall"); + } + return ret; + } + + private boolean applyType(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean obj, HashMap registerVars, boolean inFunction, boolean inMethod, List variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + boolean ret = obj; + ParsedSymbol s = lex(); + if (s.type == SymbolType.TYPENAME) { + //List params = new ArrayList<>(); + do { + s = lex(); + if (s.isType(SymbolType.MULTIPLY)) { + //params.add(new NullAVM2Item(null, null)); + } else { + lexer.pushback(s); + //params.add(; + expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false, variables, abc); + + } + s = lex(); + } while (s.type == SymbolType.COMMA); + if (s.type == SymbolType.USHIFT_RIGHT) { + s = new ParsedSymbol(s.position + 2, SymbolGroup.OPERATOR, SymbolType.GREATER_THAN); + lexer.pushback(s); + s = new ParsedSymbol(s.position + 1, SymbolGroup.OPERATOR, SymbolType.GREATER_THAN); + lexer.pushback(s); + } + if (s.type == SymbolType.SHIFT_RIGHT) { + s = new ParsedSymbol(s.position + 1, SymbolGroup.OPERATOR, SymbolType.GREATER_THAN); + lexer.pushback(s); + } + expected(s, lexer.yyline(), SymbolType.GREATER_THAN); + //ret = new ApplyTypeAVM2Item(null, null, ret, params); + ret = true; + } else { + lexer.pushback(s); + } + return ret; + } + + private boolean member(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean obj, HashMap registerVars, boolean inFunction, boolean inMethod, List variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + if (debugMode) { + System.out.println("member:"); + } + boolean ret = obj; + ParsedSymbol s = lex(); + while (s.isType(SymbolType.DOT, SymbolType.NULL_DOT, SymbolType.BRACKET_OPEN, SymbolType.TYPENAME)) { + ParsedSymbol s2 = lex(); + boolean attr = false; + boolean nullDot = false; + if (s.type == SymbolType.NULL_DOT) { + nullDot = true; + lexer.pushback(s2); + } else if (s.type == SymbolType.DOT) { + if (s2.type == SymbolType.ATTRIBUTE) { + attr = true; + } else { + lexer.pushback(s2); + } + } else { + lexer.pushback(s2); + } + if (s.type == SymbolType.TYPENAME) { + lexer.pushback(s); + //ret = ; + applyType(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables, abc); + ret = true; + s = lex(); + } else if (s.type == SymbolType.BRACKET_OPEN) { + //GraphTargetItem index = ; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + expectedType(SymbolType.BRACKET_CLOSE); + //ret = new IndexAVM2Item(attr, ret, index, null, openedNamespaces); + ret = true; + s = lex(); + } else { + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.MULTIPLY); + String propName = s.value.toString(); //Can be * + int propPosition = s.position; + //GraphTargetItem propItem = null; + s = lex(); + //String nsSuffix = ""; + //GraphTargetItem ns = null; + if (s.type == SymbolType.NAMESPACE_OP) { + //ns = new UnresolvedAVM2Item(new ArrayList<>(), importedClasses, false, null, lexer.yyline(), new DottedChain(new String[]{propName}, new String[]{""} /*FIXME ???*/), null, openedNamespaces, abcIndex); + //variables.add((UnresolvedAVM2Item) ns); + variables.add(new Variable(false, propName, propPosition)); + s = lex(); + if (s.type == SymbolType.BRACKET_OPEN) { + //propItem = ; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + expectedType(SymbolType.BRACKET_CLOSE); + //propName = null; + } else { + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + ///propName = s.value.toString(); + //propItem = null; + } + } else { + if (s.type == SymbolType.NAMESPACESUFFIX) { + //nsSuffix = "#" + s.value; + } else { + lexer.pushback(s); + } + } + /* + if (ns != null) { + ret = new NamespacedAVM2Item(ns, propName, propItem, ret, attr, openedNamespaces, null); + } else { + ret = new PropertyAVM2Item(ret, attr, propName, nsSuffix, abcIndex, openedNamespaces, new ArrayList<>(), nullDot); + }*/ + ret = true; + s = lex(); + } + } + lexer.pushback(s); + + if (debugMode) { + System.out.println("/member"); + } + return ret; + } + + private boolean name(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, boolean typeOnly, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables, List importedClasses, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + ParsedSymbol s = lex(); + DottedChain name = new DottedChain(new String[]{}, new String[]{""}); + boolean attribute = false; + String name2 = ""; + if (s.type == SymbolType.ATTRIBUTE) { + attribute = true; + s = lex(); + } + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.THIS, SymbolType.SUPER, SymbolType.STRING_OP); + name2 += s.value.toString(); + int identPos = s.position; + s = lex(); + boolean attrBracket = false; + String nsSuffix = ""; + if (s.type == SymbolType.NAMESPACESUFFIX) { + s = lex(); + nsSuffix = "#" + s.value; + } + + name = name.add(attribute, name2, nsSuffix); + //variables.add(new Variable(false, name.toPrintableString(true), identPos)); + while (s.isType(SymbolType.DOT)) { + variables.add(new Variable(false, name.toPrintableString(true), identPos)); + //name += s.value.toString(); //. or :: + s = lex(); + name2 = ""; + attribute = false; + if (s.type == SymbolType.ATTRIBUTE) { + attribute = true; + s = lex(); + if (s.type == SymbolType.MULTIPLY) { + name2 += s.value.toString(); + identPos = s.position; + } else if (s.group == SymbolGroup.IDENTIFIER) { + name2 += s.value.toString(); + identPos = s.position; + } else { + if (s.type != SymbolType.BRACKET_OPEN) { + throw new AVM2ParseException("Attribute identifier or bracket expected", lexer.yyline(), s.position); + } + attrBracket = true; + continue; + } + } else { + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.NAMESPACE, SymbolType.MULTIPLY); + name2 += s.value.toString(); + identPos = s.position; + } + s = lex(); + nsSuffix = ""; + if (s.type == SymbolType.NAMESPACESUFFIX) { + nsSuffix = "#" + s.value; + s = lex(); + } + name = name.add(attribute, name2, nsSuffix); + } + String nsname = null; + String nsprop = null; + boolean nsAtribute = false; + GraphTargetItem nspropItem = null; + if (s.type == SymbolType.NAMESPACE_OP) { + nsname = name.getLast(); + nsAtribute = name.isLastAttribute(); + s = lex(); + if (s.group == SymbolGroup.IDENTIFIER) { + nsprop = s.value.toString(); + variables.add(new Variable(false, (nsAtribute ? "@" : "") + nsname + "::" + nsprop, s.position)); + } else if (s.type == SymbolType.BRACKET_OPEN) { + //nspropItem = + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + expectedType(SymbolType.BRACKET_CLOSE); + } + name = name.getWithoutLast(); + s = lex(); + } else { + variables.add(new Variable(false, name.toPrintableString(true), identPos)); + } + + boolean ret = false; + if (!name.isEmpty()) { + //UnresolvedAVM2Item unr = new UnresolvedAVM2Item(new ArrayList<>(), importedClasses, typeOnly, null, lexer.yyline(), name, null, openedNamespaces, abcIndex); + //variables.add(unr); + //variables.add(new Variable(false, name.toPrintableString(true), )) + //ret = unr; + ret = true; + } + if (nsname != null) { + //UnresolvedAVM2Item ns = new UnresolvedAVM2Item(new ArrayList<>(), importedClasses, typeOnly, null, lexer.yyline(), new DottedChain(new String[]{nsname}), null, openedNamespaces, abcIndex); + //variables.add(ns); + //ret = new NamespacedAVM2Item(ns, nsprop, nspropItem, ret, nsAtribute, openedNamespaces, null); + } + if (s.type == SymbolType.BRACKET_OPEN) { + lexer.pushback(s); + if (attrBracket) { + lexer.pushback(new ParsedSymbol(s.position - 1, SymbolGroup.OPERATOR, SymbolType.ATTRIBUTE, "@")); + lexer.pushback(new ParsedSymbol(s.position - 2, SymbolGroup.OPERATOR, SymbolType.DOT, ".")); + } + ret = member(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables, abc); + } else { + lexer.pushback(s); + } + return ret; + } + + private void expected(ParsedSymbol symb, int line, Object... expected) throws IOException, AVM2ParseException, SimpleParseException { + boolean found = false; + for (Object t : expected) { + if (symb.type == t) { + found = true; + } + if (symb.group == t) { + found = true; + } + } + if (!found) { + String expStr = ""; + boolean first = true; + for (Object e : expected) { + if (!first) { + expStr += " or "; + } + expStr += e; + first = false; + } + throw new AVM2ParseException("" + expStr + " expected but " + symb.type + " found", line, symb.position); + } + } + + private ParsedSymbol expectedType(Object... type) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + ParsedSymbol symb = lex(); + expected(symb, lexer.yyline(), type); + return symb; + } + + private ParsedSymbol lex() throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + if (CancellableWorker.isInterrupted()) { + throw new InterruptedException(); + } + ParsedSymbol ret = lexer.lex(); + if (debugMode) { + System.out.println(ret); + } + return ret; + } + + private List call(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + List ret = new ArrayList<>(); + //expected(SymbolType.PARENT_OPEN); //MUST BE HANDLED BY CALLER + ParsedSymbol s = lex(); + while (s.type != SymbolType.PARENT_CLOSE) { + if (s.type != SymbolType.COMMA) { + lexer.pushback(s); + } + //ret.add(; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + s = lex(); + expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.PARENT_CLOSE); + } + return ret; + } + + private void method(List> allOpenedNamespaces, boolean outsidePackage, boolean isPrivate, List>> metadata, NamespaceItem pkg, boolean isInterface, boolean isNative, String customAccess, Reference needsActivation, List importedClasses, boolean override, boolean isFinal, TypeItem thisType, List openedNamespaces, boolean isStatic, String functionName, boolean isMethod, List variables, ABC abc, int methodNamePos) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + //FunctionAVM2Item f = ; + function(allOpenedNamespaces, metadata, pkg, isInterface, isNative, needsActivation, importedClasses, thisType, openedNamespaces, functionName, isMethod, variables, abc, methodNamePos); + //return new MethodAVM2Item(allOpenedNamespaces, outsidePackage, isPrivate, f.metadata, f.pkg, f.isInterface, f.isNative, customAccess, f.needsActivation, f.hasRest, f.line, override, isFinal, isStatic, functionName, f.paramTypes, f.paramNames, f.paramValues, f.body, f.subvariables, f.retType); + } + + private void function(List> allOpenedNamespaces, List>> metadata, NamespaceItem pkg, boolean isInterface, boolean isNative, Reference needsActivation, List importedClasses, TypeItem thisType, List openedNamespaces, String functionName, boolean isMethod, List variables, ABC abc, int functionNamePos) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + + openedNamespaces = new ArrayList<>(openedNamespaces); //local copy + allOpenedNamespaces.add(openedNamespaces); + int line = lexer.yyline(); + ParsedSymbol s; + expectedType(SymbolType.PARENT_OPEN); + s = lex(); + List paramNames = new ArrayList<>(); + List paramPositions = new ArrayList<>(); + //List paramTypes = new ArrayList<>(); + //List paramValues = new ArrayList<>(); + boolean hasRest = false; + while (s.type != SymbolType.PARENT_CLOSE) { + if (s.type != SymbolType.COMMA) { + lexer.pushback(s); + } + s = lex(); + if (s.type == SymbolType.REST) { + hasRest = true; + s = lex(); + } + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + + paramNames.add(s.value.toString()); + paramPositions.add(s.position); + s = lex(); + if (!hasRest) { + GraphTargetItem currentType; + if (s.type == SymbolType.COLON) { + //paramTypes.add(currentType = ; + type(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables, abc); + s = lex(); + } else { + //paramTypes.add(currentType = TypeItem.UNBOUNDED); + } + if (s.type == SymbolType.ASSIGN) { + //GraphTargetItem currentValue =; + expression(allOpenedNamespaces, thisType, pkg, new Reference<>(false), importedClasses, openedNamespaces, null, isMethod, isMethod, isMethod, variables, false, abc); + //paramValues.add(currentValue); + s = lex(); + } /*else if (!paramValues.isEmpty()) { + throw new AVM2ParseException("Some of parameters do not have default values", lexer.yyline()); + }*/ + } + + if (!s.isType(SymbolType.COMMA, SymbolType.PARENT_CLOSE)) { + expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.PARENT_CLOSE); + } + if (hasRest) { + expected(s, lexer.yyline(), SymbolType.PARENT_CLOSE); + } + } + s = lex(); + //GraphTargetItem retType; + if (s.type == SymbolType.COLON) { + //retType = ; + type(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables, abc); + } else { + //retType = TypeItem.UNBOUNDED; + lexer.pushback(s); + } + List body = null; + List subvariables = new ArrayList<>(); + if (functionName != null && !functionName.isEmpty()) { + subvariables.add(new Variable(true, functionName, functionNamePos)); + } + //subvariables.add(new NameAVM2Item(thisType, lexer.yyline(), false, "this", "", null, true, openedNamespaces, abcIndex, false)); + for (int i = 0; i < paramNames.size() - (hasRest ? 1 : 0); i++) { + subvariables.add(new Variable(true, paramNames.get(i), paramPositions.get(i))); + //subvariables.add(new NameAVM2Item(paramTypes.get(i), lexer.yyline(), false, paramNames.get(i), "", null, true, openedNamespaces, abcIndex, false)); + + } + if (hasRest) { + subvariables.add(new Variable(true, paramNames.get(paramNames.size() - 1), paramPositions.get(paramNames.size() - 1))); + //subvariables.add(new NameAVM2Item(TypeItem.UNBOUNDED, lexer.yyline(), false, paramNames.get(paramNames.size() - 1), "", null, true, openedNamespaces, abcIndex, false)); + } + subvariables.add(new Variable(true, "arguments", -1)); //??? FIXME + //subvariables.add(new NameAVM2Item(thisType, lexer.yyline(), false, "arguments", "", null, true, openedNamespaces, abcIndex, false)); + int parCnt = subvariables.size(); + Reference needsActivation2 = new Reference<>(false); + if (!isInterface && !isNative) { + expectedType(SymbolType.CURLY_OPEN); + //body = ; + commands(allOpenedNamespaces, thisType, pkg, needsActivation2, importedClasses, openedNamespaces, new Stack<>(), new HashMap<>(), new HashMap<>(), true, isMethod, 0, subvariables, abc); + expectedType(SymbolType.CURLY_CLOSE); + } else { + expectedType(SymbolType.SEMICOLON); + } + + /*for (int i = 0; i < parCnt; i++) { + subvariables.remove(0); + }*/ + //return new FunctionAVM2Item(metadata, pkg, isInterface, isNative, needsActivation2.getVal(), hasRest, line, functionName, paramTypes, paramNames, paramValues, body, subvariables, retType); + FunctionScope fs = new FunctionScope(subvariables); + variables.add(fs); + } + + private List>> parseMetadata() throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + List>> metadata = new ArrayList<>(); + ParsedSymbol s = lex(); + while (s.isType(SymbolType.BRACKET_OPEN)) { + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String name = s.value.toString(); + Map.Entry> en = new AbstractMap.SimpleEntry<>(name, new HashMap()); + s = lex(); + if (s.isType(SymbolType.PARENT_OPEN)) { + s = lex(); + if (s.isType(SymbolGroup.STRING)) { + en.getValue().put("", s.value.toString()); + s = lex(); + } else { + lexer.pushback(s); + do { + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String key = s.value.toString(); + expectedType(SymbolType.ASSIGN); + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.STRING); + String value = s.value.toString(); + en.getValue().put(key, value); + s = lex(); + } while (s.isType(SymbolType.COMMA)); + } + expected(s, lexer.yyline(), SymbolType.PARENT_CLOSE); + s = lex(); + } + expected(s, lexer.yyline(), SymbolType.BRACKET_CLOSE); + s = lex(); + + /* + * Skip Embed metadata - these are loaded automatically by the + * assignment in SymbolClass tag + */ + if (!"Embed".equals(name)) { + metadata.add(en); + } + } + lexer.pushback(s); + return metadata; + } + + private void classTraits(List> allOpenedNamespaces, boolean outsidePackage, Reference cinitNeedsActivation, List cinit, List importedClasses, List openedNamespaces, NamespaceItem pkg, String classNameStr, boolean isInterface, List traits, Reference iinitNeedsActivation, Reference iinit, ABC abc, List classVariables) throws AVM2ParseException, SimpleParseException, IOException, CompilationException, InterruptedException { + + /*NamespaceItem publicNs = new NamespaceItem("", Namespace.KIND_PACKAGE); + NamespaceItem privateNs = new NamespaceItem(pkg.name.toRawString().isEmpty() ? classNameStr : pkg.name.toRawString() + ":" + classNameStr, Namespace.KIND_PRIVATE); + NamespaceItem protectedNs = new NamespaceItem(pkg.name.toRawString().isEmpty() ? classNameStr : pkg.name.toRawString() + ":" + classNameStr, Namespace.KIND_PROTECTED); + NamespaceItem staticProtectedNs = new NamespaceItem(pkg.name.toRawString().isEmpty() ? classNameStr : pkg.name.toRawString() + ":" + classNameStr, Namespace.KIND_STATIC_PROTECTED); + NamespaceItem packageInternalNs = new NamespaceItem(pkg.name, Namespace.KIND_PACKAGE_INTERNAL); + NamespaceItem interfaceNs = new NamespaceItem(pkg.name.toRawString().isEmpty() ? classNameStr : pkg.name.toRawString() + ":" + classNameStr, Namespace.KIND_NAMESPACE); +*/ + openedNamespaces = new ArrayList<>(openedNamespaces); + /*allOpenedNamespaces.add(openedNamespaces); + for (List ln : allOpenedNamespaces) { + if (!ln.contains(publicNs)) { + ln.add(publicNs); + } + } + openedNamespaces.add(privateNs); + openedNamespaces.add(protectedNs); + openedNamespaces.add(staticProtectedNs); +*/ + Stack cinitLoops = new Stack<>(); + Map cinitLoopLabels = new HashMap<>(); + HashMap cinitRegisterVars = new HashMap<>(); + + looptraits: + while (true) { + //TypeItem thisType = new TypeItem(pkg.name.addWithSuffix(classNameStr)); + TypeItem thisType = null; + boolean isGetter = false; + boolean isSetter = false; + boolean isOverride = false; + boolean isStatic = false; + boolean isFinal = false; + boolean isPrivate = false; + boolean isNative = false; + + String customNs = null; + List preSymbols = new ArrayList<>(); + String rawCustomNs = null; + NamespaceItem namespace = null; + //static class initializer + /*if (s.type == SymbolType.CURLY_OPEN) { + cinit.addAll(commands(allOpenedNamespaces, thisType, pkg, cinitNeedsActivation, importedClasses, openedNamespaces, new Stack<>(), new HashMap<>(), new HashMap<>(), true, false, 0, cinitVariables, abc)); + expectedType(SymbolType.CURLY_CLOSE); + } else { + lexer.pushback(s); + }*/ + List>> metadata = parseMetadata(); + //s = lex(); + + ParsedSymbol s = lex(); + while (s.isType(SymbolType.NATIVE, SymbolType.STATIC, SymbolType.PUBLIC, SymbolType.PRIVATE, SymbolType.PROTECTED, SymbolType.OVERRIDE, SymbolType.FINAL, SymbolType.DYNAMIC, SymbolGroup.IDENTIFIER, SymbolType.INTERNAL, SymbolType.PREPROCESSOR)) { + if (s.type == SymbolType.FINAL) { + if (isFinal) { + throw new AVM2ParseException("Only one final keyword allowed", lexer.yyline(), s.position); + } + preSymbols.add(s); + isFinal = true; + } else if (s.type == SymbolType.OVERRIDE) { + if (isOverride) { + throw new AVM2ParseException("Only one override keyword allowed", lexer.yyline(), s.position); + } + preSymbols.add(s); + isOverride = true; + } else if (s.type == SymbolType.STATIC) { + if (isInterface) { + throw new AVM2ParseException("Interface cannot have static traits", lexer.yyline(), s.position); + } + if (classNameStr == null) { + throw new AVM2ParseException("No static keyword allowed here", lexer.yyline(), s.position); + } + if (isStatic) { + throw new AVM2ParseException("Only one static keyword allowed", lexer.yyline(), s.position); + } + preSymbols.add(s); + isStatic = true; + } else if (s.type == SymbolType.NAMESPACE) { + preSymbols.add(s); + break; + } else if (s.type == SymbolType.NATIVE) { + if (isNative) { + throw new AVM2ParseException("Only one native keyword allowed", lexer.yyline(), s.position); + } + preSymbols.add(s); + isNative = true; + } else if (s.group == SymbolGroup.IDENTIFIER) { + customNs = s.value.toString(); + if (isInterface) { + throw new AVM2ParseException("Namespace attributes are not permitted on interface methods", lexer.yyline(), s.position); + } + preSymbols.add(s); + } else if (namespace != null) { + throw new AVM2ParseException("Only one access identifier allowed", lexer.yyline(), s.position); + } + switch (s.type) { + case PUBLIC: + //namespace = publicNs; + if (isInterface) { + throw new AVM2ParseException("Interface members cannot be declared public, private, protected, or internal", lexer.yyline(), s.position); + } + preSymbols.add(s); + break; + case PRIVATE: + isPrivate = true; + //namespace = privateNs; + if (isInterface) { + throw new AVM2ParseException("Interface members cannot be declared public, private, protected, or internal", lexer.yyline(), s.position); + } + preSymbols.add(s); + break; + case PROTECTED: + //namespace = protectedNs; + if (isInterface) { + throw new AVM2ParseException("Interface members cannot be declared public, private, protected, or internal", lexer.yyline(), s.position); + } + preSymbols.add(s); + break; + case INTERNAL: + //namespace = packageInternalNs; + if (isInterface) { + throw new AVM2ParseException("Interface members cannot be declared public, private, protected, or internal", lexer.yyline(), s.position); + } + preSymbols.add(s); + break; + case PREPROCESSOR: + if (((String) s.value).toLowerCase().equals("namespace")) { + preSymbols.add(s); + s = lex(); + expected(s, lexer.yyline(), SymbolType.PARENT_OPEN); + preSymbols.add(s); + s = lex(); + expected(s, lexer.yyline(), SymbolType.STRING); + preSymbols.add(s); + namespace = new NamespaceItem((String) s.value, Namespace.KIND_NAMESPACE); + s = lex(); + expected(s, lexer.yyline(), SymbolType.PARENT_CLOSE); + preSymbols.add(s); + + } else { + lexer.pushback(s); + } + break; + } + s = lex(); + } + + /*if (isInterface) { + namespace = interfaceNs; + } + + if (namespace == null && customNs == null) { + namespace = packageInternalNs; + } + if (namespace == protectedNs && isStatic) { + namespace = staticProtectedNs; + } + if (namespace == null && customNs != null) { + //Special: it will be resolved later: + namespace = new NamespaceItem(customNs, NamespaceItem.KIND_NAMESPACE_CUSTOM); + }*/ + + switch (s.type) { + case FUNCTION: + s = lex(); + if (s.type == SymbolType.GET) { + isGetter = true; + s = lex(); + } else if (s.type == SymbolType.SET) { + isSetter = true; + s = lex(); + } + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.PARENT_OPEN); + String fname = null; + int fnamePos = s.position; + + //fix for methods with name "get" or "set" - they are not getters/setters! + if (s.isType(SymbolType.PARENT_OPEN)) { + lexer.pushback(s); + if (isGetter) { + fname = "get"; + isGetter = false; + } else if (isSetter) { + fname = "set"; + isSetter = false; + } else { + throw new AVM2ParseException("Missing method name", lexer.yyline(), s.position); + } + } else { + fname = s.value.toString(); + } + if (fname.equals(classNameStr)) { //constructor + if (isStatic) { + throw new AVM2ParseException("Constructor cannot be static", lexer.yyline(), s.position); + } + if (isOverride) { + throw new AVM2ParseException("Override flag not allowed for constructor", lexer.yyline(), s.position); + } + if (isFinal) { + throw new AVM2ParseException("Final flag not allowed for constructor", lexer.yyline(), s.position); + } + if (isInterface) { + throw new AVM2ParseException("Interface cannot have constructor", lexer.yyline(), s.position); + } + //iinit.setVal(; + method(allOpenedNamespaces, outsidePackage, isPrivate, metadata, pkg, false, false, customNs, iinitNeedsActivation, importedClasses, false, false, thisType, openedNamespaces, false, "", true, classVariables,abc, fnamePos); + } else { + GraphTargetItem t; + if (classNameStr == null) { + isStatic = true; + } + + s = lex(); + if (s.type == SymbolType.NAMESPACESUFFIX) { + namespace = new NamespaceItem((Integer) s.value); + } else { + lexer.pushback(s); + } + + //MethodAVM2Item ft; + //ft = ; + method(allOpenedNamespaces, outsidePackage, isPrivate, metadata, namespace, isInterface, isNative, customNs, new Reference<>(false), importedClasses, isOverride, isFinal, thisType, openedNamespaces, isStatic, fname, true, classVariables, abc, fnamePos); + + /*if (isGetter) { + if (!ft.paramTypes.isEmpty()) { + throw new AVM2ParseException("Getter can't have any parameters", lexer.yyline()); + } + }*/ + + /*if (isSetter) { + if (ft.paramTypes.size() != 1) { + throw new AVM2ParseException("Getter must have exactly one parameter", lexer.yyline()); + } + }*/ + + /*if (isStatic && isInterface) { + if (isInterface) { + throw new AVM2ParseException("Interface cannot have static fields", lexer.yyline()); + } + } + if (isGetter) { + GetterAVM2Item g = new GetterAVM2Item(allOpenedNamespaces, outsidePackage, ft.isPrivate(), ft.metadata, ft.pkg, isInterface, isNative, customNs, ft.needsActivation, ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType); + t = g; + } else if (isSetter) { + SetterAVM2Item st = new SetterAVM2Item(allOpenedNamespaces, outsidePackage, ft.isPrivate(), ft.metadata, ft.pkg, isInterface, isNative, customNs, ft.needsActivation, ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType); + t = st; + } else { + t = ft; + } + + traits.add(t);*/ + } + //} + break; + case NAMESPACE: + if (isInterface) { + throw new AVM2ParseException("Interface cannot have namespace fields", lexer.yyline(), s.position); + } + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String nname = s.value.toString(); + String nval; + s = lex(); + + boolean generatedNs = false; + if (s.type == SymbolType.ASSIGN) { + s = lex(); + expected(s, lexer.yyline(), SymbolType.STRING); + nval = s.value.toString(); + s = lex(); + } else { + nval = (pkg.name.toRawString() + ":" + classNameStr) + "/" + nname; + generatedNs = true; + } + if (s.type != SymbolType.SEMICOLON) { + lexer.pushback(s); + } + + ConstAVM2Item ns = new ConstAVM2Item(metadata, namespace, customNs, true, nname, new TypeItem(DottedChain.NAMESPACE), new StringAVM2Item(null, null, nval), lexer.yyline(), generatedNs); + traits.add(ns); + break; + case CONST: + case VAR: + boolean isConst = s.type == SymbolType.CONST; + if (isOverride) { + throw new AVM2ParseException("Override flag not allowed for " + (isConst ? "consts" : "vars"), lexer.yyline(), s.position); + } + if (isFinal) { + throw new AVM2ParseException("Final flag not allowed for " + (isConst ? "consts" : "vars"), lexer.yyline(), s.position); + } + if (isInterface) { + throw new AVM2ParseException("Interface cannot have variable/const fields", lexer.yyline(), s.position); + } + + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String vcname = s.value.toString(); + s = lex(); + + if (s.type == SymbolType.NAMESPACESUFFIX) { + namespace = new NamespaceItem((Integer) s.value); + s = lex(); + } + + //GraphTargetItem type; + if (s.type == SymbolType.COLON) { + //type = ; + type(allOpenedNamespaces, thisType, pkg, new Reference<>(false), importedClasses, openedNamespaces, classVariables, abc); + s = lex(); + } else { + //type = TypeItem.UNBOUNDED; + } + + //GraphTargetItem value = null; + + if (s.type == SymbolType.ASSIGN) { + //value = ; + expression(allOpenedNamespaces, thisType, pkg, new Reference<>(false), importedClasses, openedNamespaces, new HashMap<>(), false, false, true, classVariables, false, abc); + s = lex(); + } + /*GraphTargetItem tar; + if (isConst) { + tar = new ConstAVM2Item(metadata, namespace, customNs, isStatic, vcname, type, value, lexer.yyline(), false); + } else { + tar = new SlotAVM2Item(metadata, namespace, customNs, isStatic, vcname, type, value, lexer.yyline()); + } + traits.add(tar);*/ + if (s.type != SymbolType.SEMICOLON) { + lexer.pushback(s); + } + break; + default: + lexer.pushback(s); + for (int i = preSymbols.size() - 1; i >= 0; i--) { + lexer.pushback(preSymbols.get(i)); + } + + //GraphTargetItem cmd = ; + boolean cmd = command(allOpenedNamespaces, null, null, cinitNeedsActivation, importedClasses, openedNamespaces, cinitLoops, cinitLoopLabels, cinitRegisterVars, true, false, 0, false, classVariables, abc); + //if (cmd != null) { + if (cmd) { + //traits.add(cmd); + //empty + } else { + break looptraits; + } + } + } + } + + private void scriptTraits( + List importedClasses, + List openedNamespaces, + List> allOpenedNamespaces, + Reference numberUsageRef, + Reference numberRoundingRef, + Reference numberPrecisionRef, + ABC abc, + Reference sinitNeedsActivation, + List sinitVariables + ) throws AVM2ParseException, SimpleParseException, IOException, CompilationException, InterruptedException { + + Stack sinitLoops = new Stack<>(); + Map sinitLoopLabels = new HashMap<>(); + + HashMap sinitRegisterVars = new HashMap<>(); + while (scriptTraitsBlock( + importedClasses, + openedNamespaces, + allOpenedNamespaces, + numberUsageRef, + numberRoundingRef, + numberPrecisionRef, + abc, + sinitNeedsActivation, + sinitLoops, + sinitLoopLabels, + sinitRegisterVars, + sinitVariables + )) { + //empty + } + } + + private boolean scriptTraitsBlock( + List importedClasses, + List openedNamespaces, + List> allOpenedNamespaces, + Reference numberUsageRef, + Reference numberRoundingRef, + Reference numberPrecisionRef, + ABC abc, + Reference sinitNeedsActivation, + Stack sinitLoops, + Map sinitLoopLabels, + HashMap sinitRegisterVars, + List sinitVariables + ) throws AVM2ParseException, SimpleParseException, SimpleParseException, IOException, CompilationException, InterruptedException { + ParsedSymbol s; + boolean inPackage = false; + s = lex(); + + + //NamespaceItem publicNs; + //NamespaceItem packageInternalNs; + DottedChain pkgName = DottedChain.TOPLEVEL; + if (s.type == SymbolType.PACKAGE) { + s = lex(); + if (s.type != SymbolType.CURLY_OPEN) { + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + pkgName = pkgName.addWithSuffix(s.value.toString()); + s = lex(); + } + while (s.type == SymbolType.DOT) { + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + pkgName = pkgName.addWithSuffix(s.value.toString()); + s = lex(); + } + expected(s, lexer.yyline(), SymbolType.CURLY_OPEN); + //publicNs = new NamespaceItem(pkgName, Namespace.KIND_PACKAGE); + //packageInternalNs = new NamespaceItem(pkgName, Namespace.KIND_PACKAGE_INTERNAL); + s = lex(); + inPackage = true; + } else { + //publicNs = null; + //packageInternalNs = new NamespaceItem(scriptName + "$" + scriptIndex, Namespace.KIND_PRIVATE); + } + lexer.pushback(s); + + allOpenedNamespaces.add(openedNamespaces); + //NamespaceItem emptyNs = new NamespaceItem("", Namespace.KIND_PACKAGE); + //openedNamespaces.add(emptyNs); + //NamespaceItem as3Ns = new NamespaceItem(AS3_NAMESPACE, Namespace.KIND_NAMESPACE); + //as3Ns.forceResolve(abcIndex); + //openedNamespaces.add(as3Ns); + + parseImportsUsages(importedClasses, openedNamespaces, numberUsageRef, numberPrecisionRef, numberRoundingRef, abc); + + boolean isEmpty = true; + + looptrait: + while (true) { + List>> metadata = parseMetadata(); + s = lex(); + boolean isFinal = false; + boolean isDynamic = false; + boolean isPublic = false; + boolean isNative = false; + //NamespaceItem ns = packageInternalNs; + List preSymbols = new ArrayList<>(); + while (s.isType(SymbolType.FINAL, SymbolType.DYNAMIC, SymbolType.PUBLIC)) { + if (s.type == SymbolType.FINAL) { + if (isFinal) { + throw new AVM2ParseException("Only one final keyword allowed", lexer.yyline(), s.position); + } + isFinal = true; + preSymbols.add(s); + } + if (s.type == SymbolType.PUBLIC) { + if (!inPackage) { + throw new AVM2ParseException("public only allowed inside package", lexer.yyline(), s.position); + + } + if (isPublic) { + throw new AVM2ParseException("Only one public keyword allowed", lexer.yyline(), s.position); + } + isPublic = true; + //ns = publicNs; + preSymbols.add(s); + } + if (s.type == SymbolType.DYNAMIC) { + if (isDynamic) { + throw new AVM2ParseException("Only one dynamic keyword allowed", lexer.yyline(), s.position); + } + isDynamic = true; + preSymbols.add(s); + } + if (s.type == SymbolType.NATIVE) { + if (isNative) { + throw new AVM2ParseException("Only one native keyword allowed", lexer.yyline(), s.position); + } + isNative = true; + preSymbols.add(s); + } + s = lex(); + } + + switch (s.type) { + case CLASS: + case INTERFACE: + isEmpty = false; + List subOpenedNamespaces = new ArrayList<>(openedNamespaces); + boolean isInterface = false; + if (s.type == SymbolType.INTERFACE) { + isInterface = true; + } + GraphTargetItem extendsTypeStr = null; + List interfaces = new ArrayList<>(); + String subNameStr; + + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + subNameStr = s.value.toString(); + s = lex(); + + boolean nullable = true; + + if (s.type == SymbolType.NOT) { + s = lex(); + nullable = false; + } else if (s.type == SymbolType.TERNAR) { + s = lex(); + } + + if (!isInterface) { + + if (s.type == SymbolType.EXTENDS) { + //extendsTypeStr = ; + type(allOpenedNamespaces, null, null, new Reference<>(false), importedClasses, openedNamespaces, sinitVariables, abc); + s = lex(); + } + if (s.type == SymbolType.IMPLEMENTS) { + do { + //GraphTargetItem implementsTypeStr = ; + type(allOpenedNamespaces, null, null, new Reference<>(false), importedClasses, openedNamespaces, sinitVariables, abc); + //interfaces.add(implementsTypeStr); + s = lex(); + } while (s.type == SymbolType.COMMA); + } + expected(s, lexer.yyline(), SymbolType.CURLY_OPEN); + } else { + if (s.type == SymbolType.EXTENDS) { + do { + //GraphTargetItem intExtendsTypeStr = ; + type(allOpenedNamespaces, null, null, new Reference<>(false), importedClasses, openedNamespaces, sinitVariables, abc); + //interfaces.add(intExtendsTypeStr); + s = lex(); + } while (s.type == SymbolType.COMMA); + } + expected(s, lexer.yyline(), SymbolType.CURLY_OPEN); + } + + /*if (extendsTypeStr != null) { + List indices = new ArrayList<>(); + List names = new ArrayList<>(); + List namespaces = new ArrayList<>(); + //FIXME for Private classes in script (?) + AVM2SourceGenerator.parentNamesAddNames(abcIndex, scriptIndex, AVM2SourceGenerator.resolveType(new SourceGeneratorLocalData(new HashMap<>(), 0, false, 0), ((TypeItem) ((UnresolvedAVM2Item) extendsTypeStr) + .resolve(null, pkgName.addWithSuffix(subNameStr).toRawString(), null, new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), new ArrayList<>())), abcIndex), indices, names, namespaces); + for (int i = 0; i < names.size(); i++) { + if (namespaces.get(i) == null || namespaces.get(i).isEmpty()) { + continue; + } + subOpenedNamespaces.add(new NamespaceItem(namespaces.get(i) + ":" + names.get(i), Namespace.KIND_STATIC_PROTECTED)); + } + }*/ + + List cinit = new ArrayList<>(); + Reference cinitNeedsActivation = new Reference<>(false); + + Reference iinit = new Reference<>(null); + List cinitVariables = new ArrayList<>(); + List iinitVariables = new ArrayList<>(); + Reference iinitNeedsActivation = new Reference<>(false); + + List subTraits = new ArrayList<>(); + + List classVariables = new ArrayList<>(); + cinitVariables = classVariables; + iinitVariables = classVariables; + + + + classTraits(allOpenedNamespaces, !inPackage, cinitNeedsActivation, cinit, importedClasses, subOpenedNamespaces, null, subNameStr, isInterface, subTraits, iinitNeedsActivation, iinit, abc, classVariables); + + sinitVariables.add(new ClassScope(classVariables)); + + /*if (isInterface) { + traits.add(new InterfaceAVM2Item(metadata, importedClasses, ns, subOpenedNamespaces, isFinal, subNameStr, interfaces, subTraits, nullable)); + } else { + traits.add(new ClassAVM2Item(metadata, importedClasses, ns, subOpenedNamespaces, isFinal, isDynamic, subNameStr, extendsTypeStr, interfaces, cinit, cinitNeedsActivation.getVal(), cinitVariables, iinit.getVal(), iinitVariables, subTraits, iinitNeedsActivation.getVal(), nullable)); + }*/ + + expectedType(SymbolType.CURLY_CLOSE); + break; + case FUNCTION: + isEmpty = false; + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String fname = s.value.toString(); + + //traits.add(; + method(allOpenedNamespaces, !inPackage, false, metadata, null, false, isNative, null, new Reference<>(false), importedClasses, false, isFinal, null, openedNamespaces, true, fname, true, sinitVariables, abc, s.position); + break; + case CONST: + case VAR: + isEmpty = false; + boolean isConst = s.type == SymbolType.CONST; + if (isFinal) { + throw new AVM2ParseException("Final flag not allowed for " + (isConst ? "consts" : "vars"), lexer.yyline(), s.position); + } + + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String vcname = s.value.toString(); + s = lex(); + //GraphTargetItem type; + if (s.type == SymbolType.COLON) { + //type = ; + type(allOpenedNamespaces, null, null, new Reference<>(false), importedClasses, openedNamespaces, sinitVariables, abc); + s = lex(); + } else { + //type = TypeItem.UNBOUNDED; + } + + //GraphTargetItem value = null; + + if (s.type == SymbolType.ASSIGN) { + //value = ; + expression(allOpenedNamespaces, null, null, new Reference<>(false), importedClasses, openedNamespaces, new HashMap<>(), false, false, true, sinitVariables, false, abc); + s = lex(); + } + /*GraphTargetItem tar; + if (isConst) { + tar = new ConstAVM2Item(metadata, ns, null, true, vcname, type, value, lexer.yyline(), false); + } else { + tar = new SlotAVM2Item(metadata, ns, null, true, vcname, type, value, lexer.yyline()); + } + traits.add(tar);*/ + if (s.type != SymbolType.SEMICOLON) { + lexer.pushback(s); + } + break; + case NAMESPACE: + isEmpty = false; + if (isFinal) { + throw new AVM2ParseException("Final flag not allowed for namespaces", lexer.yyline(), s.position); + } + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String nname = s.value.toString(); + //String nval; + s = lex(); + + boolean generatedNs = false; + if (s.type == SymbolType.ASSIGN) { + s = lex(); + expected(s, lexer.yyline(), SymbolType.STRING); + //nval = s.value.toString(); + s = lex(); + } else { + generatedNs = true; + //nval = ns.name.toRawString() + ":" + nname; + } + if (s.type != SymbolType.SEMICOLON) { + lexer.pushback(s); + } + + //traits.add(new ConstAVM2Item(metadata, ns, null, true, nname, new TypeItem(DottedChain.NAMESPACE), new StringAVM2Item(null, null, nval), lexer.yyline(), generatedNs)); + break; + default: + lexer.pushback(s); + + for (int i = preSymbols.size() - 1; i >= 0; i--) { + lexer.pushback(preSymbols.get(i)); + } + + if (parseImportsUsages(importedClasses, openedNamespaces, numberUsageRef, numberPrecisionRef, numberRoundingRef, abc)) { + break; + } + boolean cmd = command(allOpenedNamespaces, null, null, sinitNeedsActivation, importedClasses, openedNamespaces, sinitLoops, sinitLoopLabels, sinitRegisterVars, true, false, 0, false, sinitVariables, abc); + if (cmd) { + //traits.add(cmd); + isEmpty = false; + } else { + break looptrait; + } + } + + } + if (inPackage) { + expectedType(SymbolType.CURLY_CLOSE); + } + return !isEmpty; + } + + private boolean expressionCommands(ParsedSymbol s, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, List variables) throws IOException, AVM2ParseException, SimpleParseException { + GraphTargetItem ret = null; + switch (s.type) { + /*case INT: + expectedType(SymbolType.PARENT_OPEN); + ret = new ToIntegerAVM2Item(null, null, expression(allOpenedNamespaces, thisType,pkg,needsActivation, importedClasses, openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); + expectedType(SymbolType.PARENT_CLOSE); + break; + case NUMBER_OP: + s = lex(); + if (s.type == SymbolType.DOT) { + VariableAVM2Item vi = new VariableAVM2Item(s.value.toString(), null, false); + variables.add(vi); + ret = memberOrCall(allOpenedNamespaces, thisType,vi, registerVars, inFunction, inMethod, variables); + } else { + expected(s, lexer.yyline(), SymbolType.PARENT_OPEN); + ret = new ToNumberAVM2Item(null, null, expression(allOpenedNamespaces, thisType,pkg,needsActivation, importedClasses, openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); + expectedType(SymbolType.PARENT_CLOSE); + } + break; + case STRING_OP: + ParsedSymbol sop = s; + s = lex(); + if (s.type == SymbolType.DOT) { + lexer.pushback(s); + VariableAVM2Item vi2 = new VariableAVM2Item(sop.value.toString(), null, false); + variables.add(vi2); + ret = memberOrCall(allOpenedNamespaces, thisType,vi2, registerVars, inFunction, inMethod, variables); + } else { + expected(s, lexer.yyline(), SymbolType.PARENT_OPEN); + ret = new ToStringAVM2Item(null, null, expression(allOpenedNamespaces, thisType,pkg,needsActivation, importedClasses, openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); + expectedType(SymbolType.PARENT_CLOSE); + ret = memberOrCall(allOpenedNamespaces, thisType,ret, registerVars, inFunction, inMethod, variables); + } + break;*/ + default: + return false; + } + //return ret; + } + + private GraphTargetItem add(Object a) { + if (a instanceof List) { + List l = (List) a; + if (l.isEmpty()) { + return null; + } + GraphTargetItem o = add(l.get(0)); + for (int i = 1; i < l.size(); i++) { + o = add(o, l.get(i)); + } + return o; + } + if (a instanceof StringBuilder) { + if (((StringBuilder) a).length() == 0) { + return null; + } + GraphTargetItem ret = new StringAVM2Item(null, null, a.toString()); + ((StringBuilder) a).setLength(0); + return ret; + } + if (a instanceof String) { + return new StringAVM2Item(null, null, (String) a); + } + if (a instanceof GraphTargetItem) { + return (GraphTargetItem) a; + } + return null; + } + + private GraphTargetItem add(Object a, Object b) { + GraphTargetItem ta = add(a); + GraphTargetItem tb = add(b); + + if ((ta instanceof StringAVM2Item) && (tb instanceof StringAVM2Item)) { + String sa = ((StringAVM2Item) ta).getValue(); + String sb = ((StringAVM2Item) tb).getValue(); + + return new StringAVM2Item(ta.getSrc(), ta.getLineStartItem(), sa + sb); + } + + if (ta == null && tb == null) { + return null; + } + if (ta == null) { + return tb; + } + if (tb == null) { + return ta; + } + return new AddAVM2Item(null, null, ta, tb); + } + + private void addS(List rets, StringBuilder sb) { + if (sb.length() > 0) { + if (!rets.isEmpty() && (rets.get(rets.size() - 1) instanceof StringAVM2Item)) { + StringAVM2Item stringItem = ((StringAVM2Item) rets.get(rets.size() - 1)); + stringItem.setValue(stringItem.getValue() + sb.toString()); + } else { + rets.add(new StringAVM2Item(null, null, sb.toString())); + } + sb.setLength(0); + } + } + + private void xmltag(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference usesVars, List openedTags, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + ParsedSymbol s; + //List rets = new ArrayList<>(); + //GraphTargetItem ret = null; + StringBuilder sb = new StringBuilder(); + loop: + do { + s = lex(); + List sub = new ArrayList<>(); + Reference subusesvars = new Reference<>(false); + switch (s.type) { + case XML_ATTRNAMEVAR_BEGIN: // {...}= add + usesVars.setVal(true); + //addS(rets, sb); + //rets.add(; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + expectedType(SymbolType.CURLY_CLOSE); + expectedType(SymbolType.ASSIGN); + sb.append("="); + lexer.yybegin(ActionScriptLexer.XMLOPENTAGATTRIB); + break; + case XML_ATTRVALVAR_BEGIN: // ={...} esc_xattr + usesVars.setVal(true); + sb.append("\""); + //addS(rets, sb); + //rets.add(new EscapeXAttrAVM2Item(null, null, ; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + sb.append("\""); + expectedType(SymbolType.CURLY_CLOSE); + lexer.yybegin(ActionScriptLexer.XMLOPENTAG); + break; + case XML_VAR_BEGIN: // {...} esc_xelem + usesVars.setVal(true); + //addS(rets, sb); + //rets.add(new EscapeXElemAVM2Item(null, null, ; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + expectedType(SymbolType.CURLY_CLOSE); + lexer.yybegin(ActionScriptLexer.XML); + break; + case XML_FINISHVARTAG_BEGIN: // add + usesVars.setVal(true); + sb.append(""); + //addS(rets, sb); + + if (openedTags.isEmpty()) { + throw new AVM2ParseException("XML : Closing unopened tag", lexer.yyline(), s.position); + } + openedTags.remove(openedTags.size() - 1); + break; + case XML_STARTVARTAG_BEGIN: // <{...}> add + //GraphTargetItem ex = ; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + expectedType(SymbolType.CURLY_CLOSE); + lexer.yybegin(ActionScriptLexer.XMLOPENTAG); + sub.add("*"); + sb.append("<"); + //addS(rets, sb); + //rets.add(ex); + //rets.addAll(; + xmltag(allOpenedNamespaces, thisType, pkg, subusesvars, sub, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables, abc); + break; + case XML_STARTTAG_BEGIN: // + sub.add(s.value.toString().trim().substring(1)); //remove < from beginning + //List st = ; + xmltag(allOpenedNamespaces, thisType, pkg, subusesvars, sub, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables, abc); + sb.append(s.value.toString()); + //addS(rets, sb); + //rets.addAll(st); + break; + case XML_FINISHTAG: + String tname = s.value.toString().substring(2, s.value.toString().length() - 1).trim(); + if (openedTags.isEmpty()) { + throw new AVM2ParseException("XML : Closing unopened tag", lexer.yyline(), s.position); + } + String lastTName = openedTags.get(openedTags.size() - 1); + if (lastTName.equals(tname) || lastTName.equals("*")) { + openedTags.remove(openedTags.size() - 1); + } else { + throw new AVM2ParseException("XML : Closing unopened tag", lexer.yyline(), s.position); + } + sb.append(s.value.toString()); + break; + case XML_STARTFINISHTAG_END: + openedTags.remove(openedTags.size() - 1); //close last tag + sb.append(s.value.toString()); + break; + case EOF: + throw new AVM2ParseException("End of file before XML finish", lexer.yyline(), s.position); + default: + sb.append(s.value.toString()); + break; + } + } while (!openedTags.isEmpty()); + //addS(rets, sb); + } + + private boolean xml(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + List openedTags = new ArrayList<>(); + //List xmlParts =; + xmltag(allOpenedNamespaces, thisType, pkg, new Reference<>(false), openedTags, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables, abc); + lexer.setEnableWhiteSpace(true); + lexer.begin(ActionScriptLexer.YYINITIAL); + ParsedSymbol s = lexer.lex(); + while (s.isType(SymbolType.XML_WHITESPACE)) { + //addS(xmlParts, new StringBuilder(s.value.toString())); + s = lexer.lex(); + } + lexer.setEnableWhiteSpace(false); + lexer.pushback(s); + //GraphTargetItem ret = add(xmlParts); + //ret = new XMLAVM2Item(ret); + //lexer.yybegin(ActionScriptLexer.YYINITIAL); + //TODO: Order of additions as in official compiler + return true; + } + + private boolean command(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, boolean mustBeCommand, List variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + LexBufferer buf = new LexBufferer(); + lexer.addListener(buf); + boolean ret = false; + if (debugMode) { + System.out.println("command:"); + } + ParsedSymbol s = lex(); + if (s.type == SymbolType.EOF) { + return false; + } + String loopLabel = null; + + if (s.group == SymbolGroup.IDENTIFIER) { + ParsedSymbol sc = lex(); + if (sc.type == SymbolType.COLON) { + loopLabel = s.value.toString(); + s = lex(); + } else { + lexer.pushback(sc); + } + } + + if (s.type == SymbolType.DEFAULT) { + ParsedSymbol sx = lex(); + if (sx.group != SymbolGroup.IDENTIFIER) { + lexer.pushback(sx); + } else if (!sx.value.equals("xml")) { + lexer.pushback(sx); + } else { + expectedType(SymbolType.NAMESPACE); + expectedType(SymbolType.ASSIGN); + //GraphTargetItem ns = ; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + //ret = new DefaultXMLNamespace(null, null, ns); + ret = true; + //TODO: use dxns for attribute namespaces instead of dxnslate + } + } + if (!ret) { + switch (s.type) { + case USE: + expectedType(SymbolType.NAMESPACE); + //GraphTargetItem ns = ; + type(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables, abc); + //openedNamespaces.add(new NamespaceItem(ns.toString(), Namespace.KIND_PACKAGE /*FIXME?*/)); + break; + case WITH: + needsActivation.setVal(true); + expectedType(SymbolType.PARENT_OPEN); + //GraphTargetItem wvar = ; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + /*if (!isNameOrProp(wvar)) { + throw new AVM2ParseException("Not a property or name", lexer.yyline()); + }*/ + expectedType(SymbolType.PARENT_CLOSE); + expectedType(SymbolType.CURLY_OPEN); + List withVars = new ArrayList<>(); + //List wcmd = ; + commands(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, withVars, abc); + variables.addAll(withVars); + /*for (AssignableAVM2Item a : withVars) { + if (a instanceof UnresolvedAVM2Item) { + UnresolvedAVM2Item ua = (UnresolvedAVM2Item) a; + ua.scopeStack.add(0, wvar); + } + }*/ + expectedType(SymbolType.CURLY_CLOSE); + //ret = new WithAVM2Item(null, null, wvar, wcmd); + //((WithAVM2Item) ret).subvariables = withVars; + //FIXME!!! + ret = true; + break; + case FUNCTION: + s = lexer.lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + needsActivation.setVal(true); + //ret = (; + function(allOpenedNamespaces, new ArrayList<>(), pkg, false, false, needsActivation, importedClasses, thisType, openedNamespaces, s.value.toString(), false, variables, abc, s.position); + ret = true; + break; + case VAR: + case CONST: + boolean isConst = s.type == SymbolType.CONST; + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String varIdentifier = s.value.toString(); + int varPos = s.position; + s = lex(); + //GraphTargetItem type; + if (s.type == SymbolType.COLON) { + //type = + type(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables, abc); + s = lex(); + } else { + //type = TypeItem.UNBOUNDED; + } + + if (s.type == SymbolType.ASSIGN) { + //GraphTargetItem varval = (; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + //NameAVM2Item vret = new NameAVM2Item(type, lexer.yyline(), false, varIdentifier, "", varval, true, openedNamespaces, abcIndex, isConst); + //variables.add((NameAVM2Item) vret); + variables.add(new Variable(true, varIdentifier, varPos)); + ret = true; + } else { + //NameAVM2Item vret = new NameAVM2Item(type, lexer.yyline(), false, varIdentifier, "", null, true, openedNamespaces, abcIndex, isConst); + //variables.add((NameAVM2Item) vret); + variables.add(new Variable(true, varIdentifier, varPos)); + lexer.pushback(s); + ret = true; + } + break; + case CURLY_OPEN: + //ret = new BlockItem(DIALECT, null, null, ; + commands(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables, abc); + expectedType(SymbolType.CURLY_CLOSE); + ret = true; + break; + /*case INCREMENT: //preincrement + case DECREMENT: //predecrement + GraphTargetItem varincdec = expression(allOpenedNamespaces, thisType,pkg,needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//name(allOpenedNamespaces, thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables); + if(!isNameOrProp(varincdec)){ + throw new ParseException("Not a property or name", lexer.yyline()); + } + if (s.type == SymbolType.INCREMENT) { + ret = new PreIncrementAVM2Item(null, null, varincdec); + } else if (s.type == SymbolType.DECREMENT) { + ret = new PreDecrementAVM2Item(null, null, varincdec); + } + break;*/ + case SUPER: //constructor call + ParsedSymbol ss2 = lex(); + if (ss2.type == SymbolType.PARENT_OPEN) { + //List args = ; + call(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables, abc); + ret = true; + //ret = new ConstructSuperAVM2Item(null, null, new LocalRegAVM2Item(null, null, 0, null, new TypeItem("Object") /*?*/), args); + } else { //no constructor call, but it could be calling parent methods... => handle in expression + lexer.pushback(ss2); + lexer.pushback(s); + } + break; + case IF: + expectedType(SymbolType.PARENT_OPEN); + //GraphTargetItem ifExpr = (; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + expectedType(SymbolType.PARENT_CLOSE); + //GraphTargetItem onTrue = ; + command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables, abc); + /*List onTrueList = new ArrayList<>(); + onTrueList.add(onTrue);*/ + s = lex(); + //List onFalseList = null; + if (s.type == SymbolType.ELSE) { + //onFalseList = new ArrayList<>(); + //onFalseList.add( + command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables, abc); + } else { + lexer.pushback(s); + } + //ret = new IfItem(DIALECT, null, null, ifExpr, onTrueList, onFalseList); + ret = true; + break; + case WHILE: + expectedType(SymbolType.PARENT_OPEN); + //List whileExpr = new ArrayList<>(); + //whileExpr.add(; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, true, abc); + expectedType(SymbolType.PARENT_CLOSE); + //List whileBody = new ArrayList<>(); + Loop wloop = new Loop(uniqId(), null, null); + if (loopLabel != null) { + loopLabels.put(wloop, loopLabel); + } + loops.push(wloop); + //whileBody.add(; + command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables, abc); + //ret = new WhileItem(DIALECT, null, null, wloop, whileExpr, whileBody); + loops.pop(); + ret = true; + break; + case DO: + //List doBody = new ArrayList<>(); + Loop dloop = new Loop(uniqId(), null, null); + loops.push(dloop); + if (loopLabel != null) { + loopLabels.put(dloop, loopLabel); + } + //doBody.add(; + command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables, abc); + + expectedType(SymbolType.WHILE); + expectedType(SymbolType.PARENT_OPEN); + //List doExpr = new ArrayList<>(); + //doExpr.add(; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, true, abc); + expectedType(SymbolType.PARENT_CLOSE); + //ret = new DoWhileItem(DIALECT, null, null, dloop, doBody, doExpr); + loops.pop(); + ret = true; + break; + case FOR: + s = lex(); + boolean forin = false; + boolean each = false; + GraphTargetItem collection = null; + if (s.type == SymbolType.EACH) { + each = true; + forin = true; + s = lex(); + } + expected(s, lexer.yyline(), SymbolType.PARENT_OPEN); + //GraphTargetItem firstCommand = ; + command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, false, variables, abc); + /*if (firstCommand instanceof NameAVM2Item) { + NameAVM2Item nai = (NameAVM2Item) firstCommand; + if (nai.isDefinition() && nai.getAssignedValue() == null) { //Declared value in for..in + firstCommand = expression1(allOpenedNamespaces, firstCommand, GraphTargetItem.NOPRECEDENCE, thisType, pkg, needsActivation, importedClasses, openedNamespaces, true, registerVars, inFunction, inMethod, true, variables, abc); + } + } + InAVM2Item inexpr = null; + if (firstCommand instanceof InAVM2Item) { + forin = true; + inexpr = (InAVM2Item) firstCommand; + } else if (forin) { + throw new AVM2ParseException("In expression required", lexer.yyline()); + } +*/ + Loop floop = new Loop(uniqId(), null, null); + loops.push(floop); + if (loopLabel != null) { + loopLabels.put(floop, loopLabel); + } + //List forFinalCommands = new ArrayList<>(); + //tem forExpr = null; + //List forFirstCommands = new ArrayList<>(); + if (!forin) { + s = lex(); + /*if (firstCommand != null) { //can be empty command + forFirstCommands.add(firstCommand); + } + */ + if (!s.isType(SymbolType.PARENT_CLOSE)) { + lexer.pushback(s); + //GraphTargetItem firstCommand = command(thisType,pkg,needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables); + //forExpr =; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + /*if (forExpr == null) { + forExpr = new TrueItem(DIALECT, null, null); + }*/ + expectedType(SymbolType.SEMICOLON); + //GraphTargetItem fcom = ; + command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables, abc); + /*if (fcom != null) { + forFinalCommands.add(fcom); + }*/ + } else { + lexer.pushback(s); + } + } + expectedType(SymbolType.PARENT_CLOSE); + List forBody = new ArrayList<>(); + //forBody.add(; + command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forin ? forinlevel + 1 : forinlevel, true, variables, abc); + /*if (forin) { + if (each) { + ret = new ForEachInAVM2Item(null, null, floop, inexpr, forBody); + } else { + + ret = new ForInAVM2Item(null, null, floop, inexpr, forBody); + } + } else { + ret = new ForItem(DIALECT, null, null, floop, forFirstCommands, forExpr, forFinalCommands, forBody); + }*/ + loops.pop(); + ret = true; + break; + case SWITCH: + Loop sloop = new Loop(-uniqId(), null, null); //negative id marks switch = no continue + loops.push(sloop); + if (loopLabel != null) { + loopLabels.put(sloop, loopLabel); + } + expectedType(SymbolType.PARENT_OPEN); + //GraphTargetItem switchExpr = ; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + expectedType(SymbolType.PARENT_CLOSE); + expectedType(SymbolType.CURLY_OPEN); + s = lex(); + /*int exprReg = 0; + for (int i = 0; i < 256; i++) { + if (!registerVars.containsValue(i)) { + registerVars.put("__switch" + uniqId(), i); + exprReg = i; + break; + } + }*/ + //List> caseIfs = new ArrayList<>(); + //List> caseCmds = new ArrayList<>(); + //List caseExprsAll = new ArrayList<>(); + //List valueMapping = new ArrayList<>(); + //int pos = 0; + while (s.type == SymbolType.CASE || s.type == SymbolType.DEFAULT) { + while (s.type == SymbolType.CASE || s.type == SymbolType.DEFAULT) { + if (s.type != SymbolType.DEFAULT) { + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, true, abc); + } + expectedType(SymbolType.COLON); + s = lex(); + //caseExprsAll.add(curCaseExpr); + //valueMapping.add(pos); + } + //pos++; + lexer.pushback(s); + //List caseCmd = ; + commands(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables, abc); + //caseCmds.add(caseCmd); + s = lex(); + } + expected(s, lexer.yyline(), SymbolType.CURLY_CLOSE); + //ret = new SwitchItem(DIALECT, null, null, sloop, switchExpr, caseExprsAll, caseCmds, valueMapping); + ret = true; + loops.pop(); + break; + case BREAK: + s = lex(); + long bloopId = 0; + if (loops.isEmpty()) { + throw new AVM2ParseException("No loop to break", lexer.yyline(), s.position); + } + if (s.group == SymbolGroup.IDENTIFIER) { + String breakLabel = s.value.toString(); + for (Loop l : loops) { + if (breakLabel.equals(loopLabels.get(l))) { + bloopId = l.id; + break; + } + } + if (bloopId == 0) { + throw new AVM2ParseException("Identifier of loop expected", lexer.yyline(), s.position); + } + } else { + lexer.pushback(s); + bloopId = loops.peek().id; + } + //ret = new BreakItem(DIALECT, null, null, bloopId); + ret = true; + break; + case CONTINUE: + s = lex(); + long cloopId = 0; + if (loops.isEmpty()) { + throw new AVM2ParseException("No loop to continue", lexer.yyline(), s.position); + } + if (s.group == SymbolGroup.IDENTIFIER) { + String continueLabel = s.value.toString(); + for (Loop l : loops) { + if (l.id < 0) { //negative id marks switch => no continue + continue; + } + if (continueLabel.equals(loopLabels.get(l))) { + cloopId = l.id; + break; + } + } + if (cloopId == -1) { + throw new AVM2ParseException("Identifier of loop expected", lexer.yyline(), s.position); + } + } else { + lexer.pushback(s); + for (int i = loops.size() - 1; i >= 0; i--) { + if (loops.get(i).id >= 0) { //no switches + cloopId = loops.get(i).id; + break; + } + } + if (cloopId <= 0) { + throw new AVM2ParseException("No loop to continue", lexer.yyline(), s.position); + } + } + //TODO: handle switch (???) + //ret = new ContinueItem(DIALECT, null, null, cloopId); + ret = true; + break; + case RETURN: + //GraphTargetItem retexpr = ; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, true, registerVars, inFunction, inMethod, true, variables, false, abc); + /*if (retexpr == null) { + ret = new ReturnVoidAVM2Item(null, null); + } else { + ret = new ReturnValueAVM2Item(null, null, retexpr); + }*/ + ret = true; + break; + case TRY: + needsActivation.setVal(true); + //List tryCommands = new ArrayList<>(); + //tryCommands.add(; + command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables, abc); + s = lex(); + boolean found = false; + //List> catchCommands = new ArrayList<>(); + //List catchExceptions = new ArrayList<>(); + int varCnt = variables.size(); + //List> catchesVars = new ArrayList<>(); + while (s.type == SymbolType.CATCH) { + expectedType(SymbolType.PARENT_OPEN); + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.THIS, SymbolType.SUPER, SymbolType.STRING_OP); + + String enamestr = s.value.toString(); + int ePos = s.position; + expectedType(SymbolType.COLON); + //GraphTargetItem etype = ; + type(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables, abc); + //NameAVM2Item e = new NameAVM2Item(etype, lexer.yyline(), false, enamestr, "", new ExceptionAVM2Item(null)/*?*/, true/*?*/, openedNamespaces, abcIndex, false); + //variables.add(e); + //catchExceptions.add(e); + //e.setSlotNumber(1); + //e.setSlotScope(Integer.MAX_VALUE); //will be changed later + expectedType(SymbolType.PARENT_CLOSE); + List catchVars = new ArrayList<>(); + expectedType(SymbolType.CURLY_OPEN); + //List cc = ; + commands(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, catchVars, abc); + expectedType(SymbolType.CURLY_CLOSE); + variables.add(new CatchScope(new Variable(true, enamestr, ePos), catchVars)); + //catchesVars.add(catchVars); + //List newVariables = new ArrayList<>(catchVars); + + /*for (int i = 0; i < newVariables.size(); i++) { + AssignableAVM2Item a = newVariables.get(i); + if (a instanceof UnresolvedAVM2Item) { + UnresolvedAVM2Item ui = (UnresolvedAVM2Item) a; + if (ui.getVariableName().equals(DottedChain.parseWithSuffix(e.getVariableName()))) { + List catchedVarAsList = new ArrayList<>(); + catchedVarAsList.add(e); + try { + ui.resolve(null, null, null, new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), catchedVarAsList); + } catch (CompilationException ex) { + // ignore + } + ui.setSlotNumber(e.getSlotNumber()); + ui.setSlotScope(e.getSlotScope()); + newVariables.remove(i); + i--; + } + + } + } + variables.addAll(newVariables);*/ + + //catchCommands.add(cc); + s = lex(); + found = true; + } + //TODO: + /*for (int i = varCnt; i < variables.size(); i++) { + AssignableAVM2Item av = variables.get(i); + if (av instanceof UnresolvedAVM2Item) { + UnresolvedAVM2Item ui = (UnresolvedAVM2Item) av; + for (NameAVM2Item e : catchExceptions) { + if (ui.getVariableName().equals(DottedChain.parseWithSuffix(e.getVariableName()))) { + try { + ui.resolve(null, null, null, new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), variables); + } catch (CompilationException ex) { + // ignore + } + ui.setSlotNumber(e.getSlotNumber()); + ui.setSlotScope(e.getSlotScope()); + } + } + } + }*/ + + //List finallyCommands = null; + if (s.type == SymbolType.FINALLY) { + //finallyCommands = new ArrayList<>(); + //finallyCommands.add(; + command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables, abc); + found = true; + s = lex(); + } + if (!found) { + expected(s, lexer.yyline(), SymbolType.CATCH, SymbolType.FINALLY); + } + lexer.pushback(s); + /*TryAVM2Item tai = new TryAVM2Item(tryCommands, null, catchCommands, finallyCommands, ""); + tai.catchVariables = catchesVars; + tai.catchExceptions2 = catchExceptions; + ret = tai;*/ + ret = true; + break; + case THROW: + //ret = new ThrowAVM2Item(null, null, ; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + ret = true; + break; + default: + //GraphTargetItem valcmd = ; + boolean valcmd = expressionCommands(s, registerVars, inFunction, inMethod, forinlevel, variables); + if (valcmd) { + ret = valcmd; + break; + } + if (s.type == SymbolType.SEMICOLON) { + //return new EmptyCommand(DIALECT); + return true; + } + lexer.pushback(s); + ret = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, true, abc); + if (debugMode) { + System.out.println("/command"); + } + } + } + if (debugMode) { + System.out.println("/command"); + } + lexer.removeListener(buf); + if (!ret) { //can be popped expression + buf.pushAllBack(lexer); + ret = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + } + s = lex(); + if ((s != null) && (s.type != SymbolType.SEMICOLON)) { + lexer.pushback(s); + } + + return ret; + + } + + /*private GraphTargetItem expressionRemainder(TypeItem thisType, String pkg, Reference needsActivation, List openedNamespaces, GraphTargetItem expr, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables, List importedClasses) throws IOException, AVM2ParseException, SimpleParseException { + GraphTargetItem ret = null; + ParsedSymbol s = lex(); + + ret = fixPrecedence(ret); + return ret; + }*/ + private boolean isNameOrProp(GraphTargetItem item) { + if (item instanceof UnresolvedAVM2Item) { + return true; //we don't know yet + } + if (item instanceof NameAVM2Item) { + return true; + } + if (item instanceof PropertyAVM2Item) { + return true; + } + return (item instanceof IndexAVM2Item); + } + + private boolean isType(GraphTargetItem item) { + if (item == null) { + return false; + } + while (item instanceof GetPropertyAVM2Item) { + item = ((GetPropertyAVM2Item) item).object; + } + return (item instanceof NameAVM2Item); + } + + private void brackets(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + ParsedSymbol s = lex(); + int arrCnt = 0; + if (s.type == SymbolType.BRACKET_OPEN) { + s = lex(); + + while (s.type != SymbolType.BRACKET_CLOSE) { + if (s.type != SymbolType.COMMA) { + lexer.pushback(s); + } + arrCnt++; + //ret.add(; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + s = lex(); + if (!s.isType(SymbolType.COMMA, SymbolType.BRACKET_CLOSE)) { + expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.BRACKET_CLOSE); + } + } + } else { + lexer.pushback(s); + } + } + + private boolean expression(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables, boolean allowComma, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + return expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, allowRemainder, variables, allowComma, abc); + } + + private boolean expression(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables, boolean allowComma, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + + //List commaItems = new ArrayList<>(); + ParsedSymbol symb; + do { + boolean prim = expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables, abc); + if (!prim) { + return false; + } + //GraphTargetItem item = ; + expression1(allOpenedNamespaces, prim, GraphTargetItem.NOPRECEDENCE, thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables, abc); + //commaItems.add(item); + symb = lex(); + } while (allowComma && symb != null && symb.type == SymbolType.COMMA); + if (symb != null) { + lexer.pushback(symb); + } + /*if (commaItems.size() == 1) { + return commaItems.get(0); + } + return new CommaExpressionItem(DIALECT, null, null, commaItems);*/ + return true; + } + + /** + * Lexer can return XML opentags instead of greater. In expression, we need + * greater sign only + * + * @param symb Symbol to fix + */ + private void xmlToLowerThanFix(ParsedSymbol symb) { + if (symb.isType(SymbolType.XML_STARTVARTAG_BEGIN, SymbolType.XML_STARTTAG_BEGIN)) { + lexer.yypushbackstr(symb.value.toString().substring(1)); //parse again as LOWER_THAN + String pb = symb.value.toString().substring(1); + symb.type = SymbolType.LOWER_THAN; + symb.group = SymbolGroup.OPERATOR; + symb.value = "<"; + if (pb.charAt(0) == '=') { + symb.type = SymbolType.LOWER_EQUAL; + symb.value = "<="; + pb = pb.substring(1); + } + lexer.yypushbackstr(pb); //parse again as LOWER_THAN + } + } + + private void regexpToDivideFix(ParsedSymbol symb) { + if (symb.isType(SymbolType.REGEXP)) { + String pb = symb.value.toString().substring(1); + symb.type = SymbolType.DIVIDE; + symb.group = SymbolGroup.OPERATOR; + symb.value = "/"; + if (pb.charAt(0) == '=') { + symb.type = SymbolType.ASSIGN_DIVIDE; + symb.value = "/="; + pb = pb.substring(1); + } + lexer.yypushbackstr(pb); //parse again as DIVIDE + + } + } + + private ParsedSymbol peekExprToken() throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + ParsedSymbol lookahead = lex(); + xmlToLowerThanFix(lookahead); + regexpToDivideFix(lookahead); + + lexer.pushback(lookahead); + return lookahead; + } + + private boolean expression1(List> allOpenedNamespaces, boolean lhs, int min_precedence, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + if (debugMode) { + System.out.println("expression1:"); + } + ParsedSymbol lookahead = peekExprToken(); + + ParsedSymbol op; + boolean rhs; + boolean mhs = false; + + //Note: algorithm from http://en.wikipedia.org/wiki/Operator-precedence_parser + //with relation operators reversed as we have precedence in reverse order + while (lookahead.type.isBinary() && lookahead.type.getPrecedence() <= /* >= on wiki */ min_precedence) { + op = lookahead; + lex(); + + //Note: Handle ternar operator as Binary + //http://stackoverflow.com/questions/13681293/how-can-i-incorporate-ternary-operators-into-a-precedence-climbing-algorithm + if (op.type == SymbolType.TERNAR) { + if (debugMode) { + System.out.println("ternar-middle:"); + } + mhs = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables, false, abc); + expectedType(SymbolType.COLON); + if (debugMode) { + System.out.println("/ternar-middle"); + } + } + + rhs = expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables, abc); + if (!rhs) { + lexer.pushback(op); + break; + } + + lookahead = peekExprToken(); + while ((lookahead.type.isBinary() && lookahead.type.getPrecedence() < /* > on wiki */ op.type.getPrecedence()) + || (lookahead.type.isRightAssociative() && lookahead.type.getPrecedence() == op.type.getPrecedence())) { + rhs = expression1(allOpenedNamespaces, rhs, lookahead.type.getPrecedence(), thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables, abc); + lookahead = peekExprToken(); + } + + switch (op.type) { + case AS: + //GraphTargetItem type = type(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); + + //lhs = new AsTypeAVM2Item(null, null, lhs, rhs); //??? + lhs = true; + allowRemainder = false; + break; + + case IN: + //lhs = new InAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + + case TERNAR: //??? + //lhs = new TernarOpItem(DIALECT, null, null, lhs, mhs, rhs); + lhs = true; + break; + case SHIFT_LEFT: + //lhs = new LShiftAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case SHIFT_RIGHT: + //lhs = new RShiftAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case USHIFT_RIGHT: + //lhs = new URShiftAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case BITAND: + //lhs = new BitAndAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case BITOR: + //lhs = new BitOrAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case DIVIDE: + //lhs = new DivideAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case MODULO: + //lhs = new ModuloAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case EQUALS: + //lhs = new EqAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case STRICT_EQUALS: + //lhs = new StrictEqAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case NOT_EQUAL: + //lhs = new NeqAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case STRICT_NOT_EQUAL: + //lhs = new StrictNeqAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case LOWER_THAN: + //lhs = new LtAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case LOWER_EQUAL: + //lhs = new LeAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case GREATER_THAN: + //lhs = new GtAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case GREATER_EQUAL: + //lhs = new GeAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case AND: + //lhs = new AndItem(DIALECT, null, null, lhs, rhs); + lhs = true; + break; + case OR: + //lhs = new OrItem(DIALECT, null, null, lhs, rhs); + lhs = true; + break; + case MINUS: + //lhs = new SubtractAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case MULTIPLY: + //lhs = new MultiplyAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case PLUS: + //lhs = new AddAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case XOR: + //lhs = new BitXorAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case INSTANCEOF: + //lhs = new InstanceOfAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case IS: + //GraphTargetItem istype = rhs; + //lhs = new IsTypeAVM2Item(null, null, lhs, istype); + lhs = true; + break; + case NULL_COALESCE: + //lhs = new NullCoalesceAVM2Item(null, null, lhs, rhs); + lhs = true; + break; + case ASSIGN: + case ASSIGN_BITAND: + case ASSIGN_BITOR: + case ASSIGN_DIVIDE: + case ASSIGN_MINUS: + case ASSIGN_MODULO: + case ASSIGN_MULTIPLY: + case ASSIGN_PLUS: + case ASSIGN_SHIFT_LEFT: + case ASSIGN_SHIFT_RIGHT: + case ASSIGN_USHIFT_RIGHT: + case ASSIGN_XOR: + case ASSIGN_AND: + case ASSIGN_OR: + /*GraphTargetItem assigned = rhs; + switch (op.type) { + case ASSIGN_BITAND: + assigned = new BitAndAVM2Item(null, null, lhs, assigned); + break; + case ASSIGN_BITOR: + assigned = new BitOrAVM2Item(null, null, lhs, assigned); + break; + case ASSIGN_DIVIDE: + assigned = new DivideAVM2Item(null, null, lhs, assigned); + break; + case ASSIGN_MINUS: + assigned = new SubtractAVM2Item(null, null, lhs, assigned); + break; + case ASSIGN_MODULO: + assigned = new ModuloAVM2Item(null, null, lhs, assigned); + break; + case ASSIGN_MULTIPLY: + assigned = new MultiplyAVM2Item(null, null, lhs, assigned); + break; + case ASSIGN_PLUS: + assigned = new AddAVM2Item(null, null, lhs, assigned); + break; + case ASSIGN_SHIFT_LEFT: + assigned = new LShiftAVM2Item(null, null, lhs, assigned); + break; + case ASSIGN_SHIFT_RIGHT: + assigned = new RShiftAVM2Item(null, null, lhs, assigned); + break; + case ASSIGN_USHIFT_RIGHT: + assigned = new URShiftAVM2Item(null, null, lhs, assigned); + break; + case ASSIGN_XOR: + assigned = new BitXorAVM2Item(null, null, lhs, assigned); + break; + case ASSIGN_AND: + assigned = new AndItem(DIALECT, null, null, lhs, assigned); + break; + case ASSIGN_OR: + assigned = new OrItem(DIALECT, null, null, lhs, assigned); + break; + case ASSIGN: + default: + //assigned = assigned; + break; + } + + if (!(lhs instanceof AssignableAVM2Item)) { + throw new AVM2ParseException("Invalid assignment", lexer.yyline()); + } + AssignableAVM2Item as = ((AssignableAVM2Item) lhs).copy(); + if ((as instanceof UnresolvedAVM2Item) || (as instanceof NameAVM2Item)) { + variables.add(as); + } + as.setAssignedValue(assigned); + if (lhs instanceof NameAVM2Item) { + ((NameAVM2Item) lhs).setDefinition(false); + } + lhs = as;*/ + lhs = true; + break; + } + } + /*if (lhs instanceof ParenthesisItem) { + GraphTargetItem coerced = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables, false, abc); + if (coerced != null && isType(((ParenthesisItem) lhs).value)) { + lhs = new CoerceAVM2Item(null, null, ((ParenthesisItem) lhs).value, coerced); + } + }*/ + + if (debugMode) { + System.out.println("/expression1"); + } + return lhs; + } + + private boolean expressionPrimary(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + if (debugMode) { + System.out.println("primary:"); + } + boolean ret = false; + ParsedSymbol s = lex(); + boolean allowMemberOrCall = false; + switch (s.type) { + case PREPROCESSOR: + expectedType(SymbolType.PARENT_OPEN); + switch ("" + s.value) { + //AS3 + case "hasnext": + //GraphTargetItem hnIndex = ; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + expectedType(SymbolType.COMMA); + //GraphTargetItem hnObject = + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + //ret = new HasNextAVM2Item(null, null, hnIndex, hnObject); + ret = true; + break; + case "newactivation": + //ret = new NewActivationAVM2Item(null, null); + ret = true; + break; + case "nextname": + //GraphTargetItem nnIndex = ; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + expectedType(SymbolType.COMMA); + //GraphTargetItem nnObject = ; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + + //ret = new NextNameAVM2Item(null, null, nnIndex, nnObject); + ret = true; + allowMemberOrCall = true; + break; + case "nextvalue": + //GraphTargetItem nvIndex = ; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + expectedType(SymbolType.COMMA); + //GraphTargetItem nvObject = ; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + + //ret = new NextNameAVM2Item(null, null, nvIndex, nvObject); + ret = true; + allowMemberOrCall = true; + break; + //Both ASs + case "dup": + //ret = new DuplicateItem(DIALECT, null, null, ; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + ret = true; + break; + case "push": + //ret = new PushItem( + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + ret = true; + break; + case "pop": + //ret = new PopItem(DIALECT, null, null); + ret = true; + break; + case "goto": + case "multiname": + throw new AVM2ParseException("Compiling §§" + s.value + " is not available, sorry", lexer.yyline(), s.position); + default: + throw new AVM2ParseException("Unknown preprocessor instruction: §§" + s.value, lexer.yyline(), s.position); + } + expectedType(SymbolType.PARENT_CLOSE); + break; + case REGEXP: + //String p = (String) s.value; + //p = p.substring(1); + //int spos = p.lastIndexOf('/'); + //String mod = p.substring(spos + 1); + //p = p.substring(0, spos); + //ret = new RegExpAvm2Item(p, mod, null, null); + allowMemberOrCall = true; + ret = true; + break; + case XML_STARTTAG_BEGIN: + case XML_STARTVARTAG_BEGIN: + case XML_CDATA: + case XML_COMMENT: + lexer.pushback(s); + ret = xml(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables, abc); + break; + case STRING: + //ret = new StringAVM2Item(null, null, s.value.toString()); + ret = true; + allowMemberOrCall = true; + break; + case NEGATE: + ret = expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false, variables, abc); + //ret = new BitNotAVM2Item(null, null, ret); + ret = true; + + break; + case PLUS: + //GraphTargetItem nump = ; + expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, true, variables, abc); + /*if (abc.hasFloatSupport()) { + ret = new UnPlusAVM2Item(null, null, nump); + } else { + ret = new CoerceAVM2Item(null, null, nump, TypeItem.NUMBER); + }*/ + ret = true; + break; + case MINUS: + s = lex(); + if (s.isType(SymbolType.DOUBLE)) { + //ret = new DoubleValueAVM2Item(null, null, -(Double) s.value); + ret = true; + } else if (s.isType(SymbolType.INTEGER)) { + //ret = new IntegerValueAVM2Item(null, null, -(Integer) s.value); + ret = true; + } else if (s.isType(SymbolType.DECIMAL)) { + //ret = new DecimalValueAVM2Item(null, null, ((Decimal128) s.value).multiply(Decimal128.NEG1)); + ret = true; + } else if (s.isType(SymbolType.FLOAT)) { + //ret = new FloatValueAVM2Item(null, null, -(Float) s.value); + ret = true; + } else { + lexer.pushback(s); + //GraphTargetItem num = ; + expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, true, variables, abc); + /*if (num instanceof IntegerValueAVM2Item) { + ((IntegerValueAVM2Item) num).value = -((IntegerValueAVM2Item) num).value; + ((IntegerValueAVM2Item) num).detectFormat(); + ret = num; + } else if (num instanceof DoubleValueAVM2Item) { + Double d = ((DoubleValueAVM2Item) num).value; + if (d.isInfinite()) { + ((DoubleValueAVM2Item) num).value = Double.NEGATIVE_INFINITY; + } else { + ((DoubleValueAVM2Item) num).value = -d; + } + ret = (num); + } else { + ret = (new NegAVM2Item(null, null, num)); + }*/ + ret = true; + } + break; + case TYPEOF: + //ret = new TypeOfAVM2Item(null, null, ; + expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false, variables, abc); + ret = true; + break; + case TRUE: + //ret = new BooleanAVM2Item(null, null, true); + ret = true; + break; + case NULL: + //ret = new NullAVM2Item(null, null); + ret = true; + break; + case UNDEFINED: + //ret = new UndefinedAVM2Item(null, null); + ret = true; + break; + case FALSE: + //ret = new BooleanAVM2Item(null, null, false); + ret = true; + break; + case CURLY_OPEN: //Object literal + s = lex(); + //List nvs = new ArrayList<>(); + + while (s.type != SymbolType.CURLY_CLOSE) { + if (s.type != SymbolType.COMMA) { + lexer.pushback(s); + } + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.STRING, SymbolType.INTEGER, SymbolType.DOUBLE, SymbolType.PARENT_OPEN); + + //GraphTargetItem n; + if (s.type == SymbolType.PARENT_OPEN) { //special for obfuscated SWFs + //n = ; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables, false, abc); + expectedType(SymbolType.PARENT_CLOSE); + } else { + //n = new StringAVM2Item(null, null, s.value.toString()); + } + expectedType(SymbolType.COLON); + //GraphTargetItem v =; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables, false, abc); + + //NameValuePair nv = new NameValuePair(n, v); + //nvs.add(nv); + s = lex(); + if (!s.isType(SymbolType.COMMA, SymbolType.CURLY_CLOSE)) { + expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.CURLY_CLOSE); + } + } + //ret = new NewObjectAVM2Item(null, null, nvs); + ret = true; + allowMemberOrCall = true; + break; + case BRACKET_OPEN: //Array literal or just brackets + lexer.pushback(s); + //List inBrackets = new ArrayList<>(); + //int arrCnt = ; + brackets(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables, abc); + //ret = new NewArrayAVM2Item(null, null, inBrackets); + ret = true; + allowMemberOrCall = true; + break; + case FUNCTION: + s = lexer.lex(); + String fname = ""; + int fnamePos = -1; + if (s.isType(SymbolGroup.IDENTIFIER)) { + fname = s.value.toString(); + fnamePos = s.position; + } else { + lexer.pushback(s); + } + needsActivation.setVal(true); + //ret = ; + function(allOpenedNamespaces, new ArrayList<>(), pkg, false, false, needsActivation, importedClasses, thisType, openedNamespaces, fname, false, variables, abc, fnamePos); + ret = true; + allowMemberOrCall = true; + break; + case NAN: + //ret = new NanAVM2Item(null, null); + ret = true; + break; + case INFINITY: + //ret = new DoubleValueAVM2Item(null, null, Double.POSITIVE_INFINITY) + ret = true; + break; + case INTEGER: + //ret = new IntegerValueAVM2Item(null, null, (Integer) s.value); + ret = true; + break; + case DOUBLE: + //ret = new DoubleValueAVM2Item(null, null, (Double) s.value); + ret = true; + allowMemberOrCall = true; // 5.2.toString(); + break; + case DECIMAL: + if (!abc.hasDecimalSupport()) { + throw new AVM2ParseException("The ABC has no decimal support", lexer.yyline(), s.position); + } + //ret = new DecimalValueAVM2Item(null, null, (Decimal128) s.value); + ret = true; + allowMemberOrCall = true; + break; + case FLOAT: + if (!abc.hasFloatSupport()) { + throw new AVM2ParseException("The ABC has no float support", lexer.yyline(), s.position); + } + //ret = new FloatValueAVM2Item(null, null, (Float) s.value); + ret = true; + allowMemberOrCall = true; + break; + case FLOAT4: + if (!abc.hasFloat4Support()) { + //parse again as method call + lexer.yypushbackstr(lexer.yytext().substring("float4".length())); + lexer.pushback(new ParsedSymbol(lexer.yychar() /*???*/, SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, "float4")); + ret = name(allOpenedNamespaces, thisType, pkg, needsActivation, false, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses, abc); + } else { + ret = true; //new Float4ValueAVM2Item(null, null, (Float4) s.value); + } + allowMemberOrCall = true; + break; + case DELETE: + //GraphTargetItem varDel = ; + expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, true, variables, abc); + /*if (!isNameOrProp(varDel)) { + throw new AVM2ParseException("Not a property or name", lexer.yyline()); + }*/ + //ret = new DeletePropertyAVM2Item(varDel, lexer.yyline()); + ret = true; + break; + case INCREMENT: + case DECREMENT: //preincrement + //GraphTargetItem varincdec = ; + expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false/*?*/, variables, abc); + /*if (!isNameOrProp(varincdec)) { + throw new AVM2ParseException("Not a property or name", lexer.yyline()); + }*/ + /*if (s.type == SymbolType.INCREMENT) { + ret = new PreIncrementAVM2Item(null, null, varincdec); + } + if (s.type == SymbolType.DECREMENT) { + ret = new PreDecrementAVM2Item(null, null, varincdec); + }*/ + ret = true; + break; + case NOT: + //ret = new NotItem(DIALECT, null, null, ; + expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false, variables, abc); + ret = true; + break; + case PARENT_OPEN: + //ret = new ParenthesisItem(DIALECT, null, null, ; + expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, true, abc); + expectedType(SymbolType.PARENT_CLOSE); + /*if (ret.value == null) { + throw new AVM2ParseException("Expression in parenthesis expected", lexer.yyline()); + }*/ + ret = true; + allowMemberOrCall = true; + break; + case NEW: + s = lex(); + if (s.type == SymbolType.XML_STARTTAG_BEGIN) { + lexer.yypushbackstr(s.value.toString().substring(1), ActionScriptLexer.YYINITIAL); + s = new ParsedSymbol(s.position, SymbolGroup.OPERATOR, SymbolType.LOWER_THAN); + } + if (s.type == SymbolType.FUNCTION) { + s = lexer.lex(); + String ffname = ""; + int ffnamePos = -1; + if (s.isType(SymbolGroup.IDENTIFIER)) { + ffname = s.value.toString(); + ffnamePos = s.position; + } else { + lexer.pushback(s); + } + needsActivation.setVal(true); + function(allOpenedNamespaces, new ArrayList<>(), pkg, false, false, needsActivation, importedClasses, thisType, openedNamespaces, ffname, false, variables, abc, ffnamePos); + ret = true; + } else if (s.type == SymbolType.LOWER_THAN) { + //GraphTargetItem subtype = ; + type(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables, abc); + expectedType(SymbolType.GREATER_THAN); + s = lex(); + expected(s, lexer.yyline(), SymbolType.BRACKET_OPEN); + lexer.pushback(s); + List params = new ArrayList<>(); + brackets(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables, abc); + //ret = new InitVectorAVM2Item(subtype, params, openedNamespaces); + ret = true; + } else if (s.type == SymbolType.PARENT_OPEN) { + //GraphTargetItem newvar = ; + boolean newvar = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables, false, abc); + //newvar = ; + applyType(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, newvar, registerVars, inFunction, inMethod, variables, abc); + expectedType(SymbolType.PARENT_CLOSE); + expectedType(SymbolType.PARENT_OPEN); + //ret = new ConstructSomethingAVM2Item(lexer.yyline(), openedNamespaces, newvar, + call(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables, abc); + //, abcIndex); + ret = true; + + } else { + lexer.pushback(s); + boolean newvar = name(allOpenedNamespaces, thisType, pkg, needsActivation, false /*?*/, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses, abc); + applyType(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, newvar, registerVars, inFunction, inMethod, variables, abc); + expectedType(SymbolType.PARENT_OPEN); + //ret = new ConstructSomethingAVM2Item(lexer.yyline(), openedNamespaces, newvar, + + call(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables, abc); + //, abcIndex); + ret = true; + } + allowMemberOrCall = true; + break; + case IDENTIFIER: + case THIS: + case SUPER: + case ATTRIBUTE: + lexer.pushback(s); + ret = name(allOpenedNamespaces, thisType, pkg, needsActivation, false, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses, abc); + allowMemberOrCall = true; + + //var = memberOrCall(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, var, registerVars, inFunction, inMethod, variables); + //ret = var; + break; + default: + boolean excmd = expressionCommands(s, registerVars, inFunction, inMethod, -1, variables); + if (excmd) { + //? + ret = excmd; + allowMemberOrCall = true; //? + break; + } + lexer.pushback(s); + } + if (allowMemberOrCall && ret) { + ret = memberOrCall(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables, abc); + } + if (debugMode) { + System.out.println("/primary"); + } + return ret; + } + + private ActionScriptLexer lexer = null; + + private List constantPool; + + private boolean parseImportsUsages(List importedClasses, List openedNamespaces, Reference numberUsageRef, Reference numberPrecisionRef, Reference numberRoundingRef, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException { + + boolean isEmpty = true; + ParsedSymbol s; + + s = lex(); + while (s.isType(SymbolType.IMPORT, SymbolType.USE)) { + + if (s.isType(SymbolType.IMPORT)) { + isEmpty = false; + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + DottedChain fullName = new DottedChain(new String[]{}); + fullName = fullName.add(s.value.toString(), ""); + s = lex(); + boolean isStar = false; + while (s.type == SymbolType.DOT) { + s = lex(); + if (s.type == SymbolType.MULTIPLY) { + isStar = true; + s = lex(); + break; + } + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + fullName = fullName.add(s.value.toString(), ""); + s = lex(); + } + + /*else if (isUse) { + //Note: in this case, fullName attribute will be changed to real NS including NamespaceItem + openedNamespaces.add(new NamespaceItem(fullName, Namespace.KIND_NAMESPACE)); + } else */ + if (isStar) { + openedNamespaces.add(new NamespaceItem(fullName, Namespace.KIND_PACKAGE)); + } else { + importedClasses.add(fullName); + } + expected(s, lexer.yyline(), SymbolType.SEMICOLON); + } else if (s.isType(SymbolType.USE)) { + isEmpty = false; + do { + s = lex(); + if (s.isType(SymbolType.NAMESPACE)) { + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + DottedChain fullName = new DottedChain(new String[]{}); + fullName = fullName.add(s.value.toString(), ""); + s = lex(); + boolean isStar = false; + while (s.type == SymbolType.DOT) { + s = lex(); + if (s.type == SymbolType.MULTIPLY) { + isStar = true; + s = lex(); + break; + } + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + fullName = fullName.add(s.value.toString(), ""); + s = lex(); + } + lexer.pushback(s); + } else { + if (!abc.hasDecimalSupport()) { + throw new AVM2ParseException("Invalid use kind", lexer.yyline(), s.position); + } + + expected(s, lexer.yyline(), SymbolType.IDENTIFIER); + String pragmaItemName = (String) s.value; + switch (pragmaItemName) { + case "Number": + numberUsageRef.setVal(NumberContext.USE_NUMBER); + break; + case "decimal": + numberUsageRef.setVal(NumberContext.USE_DECIMAL); + break; + case "double": + numberUsageRef.setVal(NumberContext.USE_DOUBLE); + break; + case "int": + numberUsageRef.setVal(NumberContext.USE_INT); + break; + case "uint": + numberUsageRef.setVal(NumberContext.USE_UINT); + break; + case "rounding": + s = lex(); + expected(s, lexer.yyline(), SymbolType.IDENTIFIER); + String roundingIdentifier = (String) s.value; + int rounding; + switch (roundingIdentifier) { + case "CEILING": + rounding = NumberContext.ROUND_CEILING; + break; + case "UP": + rounding = NumberContext.ROUND_UP; + break; + case "HALF_UP": + rounding = NumberContext.ROUND_HALF_UP; + break; + case "HALF_EVEN": + rounding = NumberContext.ROUND_HALF_EVEN; + break; + case "HALF_DOWN": + rounding = NumberContext.ROUND_HALF_DOWN; + break; + case "DOWN": + rounding = NumberContext.ROUND_DOWN; + break; + case "FLOOR": + rounding = NumberContext.ROUND_FLOOR; + break; + default: + throw new AVM2ParseException("Rounding expected - one of: CEILING, UP, HALF_UP, HALF_EVEN, HALF_DOWN, DOWN, FLOOR", lexer.yyline(), s.position); + } + numberRoundingRef.setVal(rounding); + break; + case "precision": + s = lex(); + expected(s, lexer.yyline(), SymbolType.INTEGER); + int precision = (Integer) s.value; + if (precision < 1 || precision > 34) { + throw new AVM2ParseException("Invalid precision - must be between 1 and 34", lexer.yyline(), s.position); + } + numberPrecisionRef.setVal(precision); + break; + default: + throw new AVM2ParseException("Invalid use kind", lexer.yyline(), s.position); + } + } + s = lex(); + } while (s.isType(SymbolType.COMMA)); + expected(s, lexer.yyline(), SymbolType.SEMICOLON); + } + /*boolean isUse = s.type == SymbolType.USE; + if (isUse) { + + expectedType(SymbolType.NAMESPACE); + }*/ + + s = lex(); + } + lexer.pushback(s); + return !isEmpty; + } + + private void parseScript( + List importedClasses, + List openedNamespaces, + List> allOpenedNamespaces, + Reference numberContextRef, + ABC abc, + Reference sinitNeedsActivation, + List sinitVariables + ) throws IOException, AVM2ParseException, SimpleParseException, CompilationException, InterruptedException { + + Reference numberUsageRef = new Reference<>(NumberContext.USE_NUMBER); + Reference numberRoundingRef = new Reference<>(NumberContext.ROUND_HALF_EVEN); + Reference numberPrecisionRef = new Reference<>(34); + scriptTraits(importedClasses, openedNamespaces, allOpenedNamespaces, numberUsageRef, numberRoundingRef, numberPrecisionRef, abc, sinitNeedsActivation, sinitVariables); + + NumberContext nc = new NumberContext(numberUsageRef.getVal(), numberPrecisionRef.getVal(), numberRoundingRef.getVal()); + if (!nc.isDefault()) { + numberContextRef.setVal(nc.toParam()); + } + } + + /** + * Converts string to script traits. + * + * @param importedClasses Imported classes + * @param openedNamespaces Opened namespaces + * @param allOpenedNamespaces All opened namespaces + * @param str String to parse + * @param numberContextRef Number context reference + * @param abc ABC + * @param sinitNeedsActivation Script initializer needs activation + * @param sinitVariables Script initializer variables + * @throws AVM2ParseException On parsing error + * @throws IOException On I/O error + * @throws CompilationException On compilation error + * @throws InterruptedException On interrupt + */ + private void scriptTraitsFromString( + List importedClasses, + List openedNamespaces, + List> allOpenedNamespaces, + String str, + Reference numberContextRef, + ABC abc, + Reference sinitNeedsActivation, + List sinitVariables + ) throws AVM2ParseException, SimpleParseException, IOException, CompilationException, InterruptedException { + lexer = new ActionScriptLexer(str); + + parseScript(importedClasses, openedNamespaces, allOpenedNamespaces, numberContextRef, abc, sinitNeedsActivation, sinitVariables); + ParsedSymbol s = lexer.lex(); + if (s.type != SymbolType.EOF) { + throw new AVM2ParseException("Parsing finished before end of the file", lexer.yyline(), s.position); + } + } + + + @Override + public void parse( + String str, + Map> definitionPosToReferences, + Map referenceToDefinition, + List errors + ) throws SimpleParseException, IOException, InterruptedException { + List> allOpenedNamespaces = new ArrayList<>(); + Reference numberContextRef = new Reference<>(null); + Reference sinitNeedsActivation = new Reference<>(false); + List vars = new ArrayList<>(); + List importedClasses = new ArrayList<>(); + List openedNamespaces = new ArrayList<>(); + try { + scriptTraitsFromString(importedClasses, openedNamespaces, allOpenedNamespaces, str, numberContextRef, abc, sinitNeedsActivation, vars); + } catch (AVM2ParseException ex) { + //Logger.getLogger(ActionScript3SimpleParser.class.getName()).log(Level.SEVERE, null, ex); + throw new SimpleParseException(str, ex.line, ex.position); + } catch (CompilationException ex) { + //Logger.getLogger(ActionScript3SimpleParser.class.getName()).log(Level.SEVERE, null, ex); + throw new SimpleParseException(str, ex.line); + } + Map varNameToDefinitionPosition = new LinkedHashMap<>(); + + parseVariablesList(new ArrayList<>(), vars, definitionPosToReferences, referenceToDefinition, varNameToDefinitionPosition); + } + + + + private void parseVariablesList( + List privateVariables, + List sharedVariables, + Map> definitionPosToReferences, + Map referenceToDefinition, + Map parentVarNameToDefinitionPosition + ) { + Map privateVarNameToDefinitionPosition = new LinkedHashMap<>(); + privateVarNameToDefinitionPosition.putAll(parentVarNameToDefinitionPosition); + + for (VariableOrScope vt : privateVariables) { + if (vt instanceof Variable) { + Variable v = (Variable) vt; + if (v.definition) { + privateVarNameToDefinitionPosition.put(v.name, v.position); + definitionPosToReferences.put(v.position, new ArrayList<>()); + } else { + if (!privateVarNameToDefinitionPosition.containsKey(v.name)) { + parentVarNameToDefinitionPosition.put(v.name, -v.position - 1); + privateVarNameToDefinitionPosition.put(v.name, -v.position - 1); + definitionPosToReferences.put(-v.position - 1, new ArrayList<>()); + definitionPosToReferences.get(-v.position - 1).add(v.position); + referenceToDefinition.put(v.position, -v.position - 1); + } else { + int definitionPos = privateVarNameToDefinitionPosition.get(v.name); + definitionPosToReferences.get(definitionPos).add(v.position); + referenceToDefinition.put(v.position, definitionPos); + } + } + } + if (vt instanceof Scope) { + Scope vs = (Scope) vt; + parseVariablesList(vs.getPrivateItems(), vs.getSharedItems(), definitionPosToReferences, referenceToDefinition, privateVarNameToDefinitionPosition); + } + } + for (VariableOrScope vt : sharedVariables) { + if (vt instanceof Variable) { + Variable v = (Variable) vt; + if (v.definition) { + parentVarNameToDefinitionPosition.put(v.name, v.position); + privateVarNameToDefinitionPosition.put(v.name, v.position); + definitionPosToReferences.put(v.position, new ArrayList<>()); + } else { + if (!privateVarNameToDefinitionPosition.containsKey(v.name)) { + parentVarNameToDefinitionPosition.put(v.name, -v.position - 1); + privateVarNameToDefinitionPosition.put(v.name, -v.position - 1); + definitionPosToReferences.put(-v.position - 1, new ArrayList<>()); + definitionPosToReferences.get(-v.position - 1).add(v.position); + referenceToDefinition.put(v.position, -v.position - 1); + } else { + int definitionPos = privateVarNameToDefinitionPosition.get(v.name); + definitionPosToReferences.get(definitionPos).add(v.position); + referenceToDefinition.put(v.position, definitionPos); + } + } + } + if (vt instanceof Scope) { + Scope vs = (Scope) vt; + parseVariablesList(vs.getPrivateItems(), vs.getSharedItems(), definitionPosToReferences, referenceToDefinition, privateVarNameToDefinitionPosition); + } + } + } + /** + * Constructor. + * @param abc ABC + */ + public ActionScript3SimpleParser(ABC abc) { + this.abc = abc; + + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptLexer.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptLexer.java index 700bcdbba..a5ec6a9ad 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptLexer.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptLexer.java @@ -1,16 +1,18 @@ +/* The following code was generated by JFlex 1.6.0 */ + /* - * Copyright (C) 2010-2025 JPEXS, All rights reserved. - * + * Copyright (C) 2010-2016 JPEXS, All rights reserved. + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3.0 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library. */ @@ -1099,6 +1101,8 @@ public final class ActionScriptLexer { private static String xmlTagName = ""; + private int startPos = -1; + public int yychar() { return yychar; } @@ -1470,47 +1474,47 @@ public final class ActionScriptLexer { case 186: break; case 2: { yyline++; - if (enableWhiteSpace) { return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_WHITESPACE, yytext()); } + if (enableWhiteSpace) { return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_WHITESPACE, yytext()); } } case 187: break; case 3: - { if (enableWhiteSpace) { return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_WHITESPACE, yytext()); } + { if (enableWhiteSpace) { return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_WHITESPACE, yytext()); } } case 188: break; case 4: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DIVIDE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.DIVIDE, yytext()); } case 189: break; case 5: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.MULTIPLY, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.MULTIPLY, yytext()); } case 190: break; case 6: - { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, yytext()); } case 191: break; case 7: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DOT, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.DOT, yytext()); } case 192: break; case 8: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.LOWER_THAN, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.LOWER_THAN, yytext()); } case 193: break; case 9: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NOT, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.NOT, yytext()); } case 194: break; case 10: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.MINUS, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.MINUS, yytext()); } case 195: break; case 11: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.GREATER_THAN, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.GREATER_THAN, yytext()); } case 196: break; case 12: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.COLON, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.COLON, yytext()); } case 197: break; case 13: @@ -1519,94 +1523,97 @@ public final class ActionScriptLexer { ival = ival.substring(0, ival.length() - 1); } try{ - return new ParsedSymbol(SymbolGroup.INTEGER, SymbolType.INTEGER, Integer.parseInt(ival)); + return new ParsedSymbol(yychar(), SymbolGroup.INTEGER, SymbolType.INTEGER, Integer.parseInt(ival)); } catch(NumberFormatException nfe){ //its too long for an Integer var - return new ParsedSymbol(SymbolGroup.DOUBLE, SymbolType.DOUBLE, Double.parseDouble(ival)); + return new ParsedSymbol(yychar(), SymbolGroup.DOUBLE, SymbolType.DOUBLE, Double.parseDouble(ival)); } } case 198: break; case 14: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.TERNAR, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.TERNAR, yytext()); } case 199: break; case 15: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BRACKET_OPEN, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.BRACKET_OPEN, yytext()); } case 200: break; case 16: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BRACKET_CLOSE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.BRACKET_CLOSE, yytext()); } case 201: break; case 17: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN, yytext()); } case 202: break; case 18: - { string.setLength(0); + { startPos = yychar(); + string.setLength(0); yybegin(STRING); } case 203: break; case 19: - { string.setLength(0); + { startPos = yychar(); + string.setLength(0); yybegin(CHARLITERAL); } case 204: break; case 20: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.PARENT_OPEN, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.PARENT_OPEN, yytext()); } case 205: break; case 21: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.COMMA, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.COMMA, yytext()); } case 206: break; case 22: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.PARENT_CLOSE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.PARENT_CLOSE, yytext()); } case 207: break; case 23: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.PLUS, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.PLUS, yytext()); } case 208: break; case 24: - { string.setLength(0); + { startPos = yychar(); + string.setLength(0); yybegin(OIDENTIFIER); } case 209: break; case 25: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ATTRIBUTE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ATTRIBUTE, yytext()); } case 210: break; case 26: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.CURLY_OPEN, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.CURLY_OPEN, yytext()); } case 211: break; case 27: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.CURLY_CLOSE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.CURLY_CLOSE, yytext()); } case 212: break; case 28: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.SEMICOLON, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.SEMICOLON, yytext()); } case 213: break; case 29: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NEGATE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.NEGATE, yytext()); } case 214: break; case 30: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BITAND, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.BITAND, yytext()); } case 215: break; case 31: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.BITOR, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.BITOR, yytext()); } case 216: break; case 32: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.XOR, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.XOR, yytext()); } case 217: break; case 33: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.MODULO, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.MODULO, yytext()); } case 218: break; case 34: @@ -1622,7 +1629,7 @@ public final class ActionScriptLexer { // length also includes the trailing quote String tos = string.toString(); string.setLength(0); - return new ParsedSymbol(SymbolGroup.STRING, SymbolType.STRING, tos); + return new ParsedSymbol(startPos, SymbolGroup.STRING, SymbolType.STRING, tos); } case 221: break; case 37: @@ -1632,7 +1639,7 @@ public final class ActionScriptLexer { case 38: { yybegin(YYINITIAL); // length also includes the trailing quote - return new ParsedSymbol(SymbolGroup.STRING, SymbolType.STRING, string.toString()); + return new ParsedSymbol(startPos, SymbolGroup.STRING, SymbolType.STRING, string.toString()); } case 223: break; case 39: @@ -1641,9 +1648,9 @@ public final class ActionScriptLexer { case 224: break; case 40: { yybegin(XML); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTTAG_END, yytext())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_STARTTAG_END, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); @@ -1651,9 +1658,9 @@ public final class ActionScriptLexer { case 225: break; case 41: { yybegin(YYINITIAL); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRNAMEVAR_BEGIN, yytext())); + pushback(new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_ATTRNAMEVAR_BEGIN, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); @@ -1661,9 +1668,9 @@ public final class ActionScriptLexer { case 226: break; case 42: { yybegin(XML); - pushback(new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.GREATER_THAN, yytext())); + pushback(new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.GREATER_THAN, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); @@ -1671,7 +1678,7 @@ public final class ActionScriptLexer { case 227: break; case 43: { yybegin(YYINITIAL); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRVALVAR_BEGIN, yytext()); + return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_ATTRVALVAR_BEGIN, yytext()); } case 228: break; case 44: @@ -1680,9 +1687,9 @@ public final class ActionScriptLexer { case 229: break; case 45: { yybegin(YYINITIAL); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_VAR_BEGIN, yytext())); + pushback(new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_VAR_BEGIN, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); @@ -1696,7 +1703,7 @@ public final class ActionScriptLexer { { yybegin(YYINITIAL); repeatNum = 1; // length also includes the trailing quote - return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, string.toString()); + return new ParsedSymbol(startPos, SymbolGroup.IDENTIFIER, SymbolType.IDENTIFIER, string.toString()); } case 232: break; case 48: @@ -1704,81 +1711,82 @@ public final class ActionScriptLexer { } case 233: break; case 49: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_DIVIDE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_DIVIDE, yytext()); } case 234: break; case 50: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_MULTIPLY, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_MULTIPLY, yytext()); } case 235: break; case 51: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DESCENDANTS, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.DESCENDANTS, yytext()); } case 236: break; case 52: - { return new ParsedSymbol(SymbolGroup.TYPENAME, SymbolType.TYPENAME, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.TYPENAME, SymbolType.TYPENAME, yytext()); } case 237: break; case 53: { String dval = yytext(); if (dval.endsWith("m")) { dval = dval.substring(0, dval.length() - 1); - return new ParsedSymbol(SymbolGroup.DECIMAL, SymbolType.DECIMAL, new Decimal128(dval)); + return new ParsedSymbol(yychar(), SymbolGroup.DECIMAL, SymbolType.DECIMAL, new Decimal128(dval)); } if (dval.endsWith("f")) { dval = dval.substring(0, dval.length() - 1); - return new ParsedSymbol(SymbolGroup.FLOAT, SymbolType.FLOAT, Float.parseFloat(dval)); + return new ParsedSymbol(yychar(), SymbolGroup.FLOAT, SymbolType.FLOAT, Float.parseFloat(dval)); } if (dval.endsWith("d")) { dval = dval.substring(0, dval.length() - 1); } - return new ParsedSymbol(SymbolGroup.DOUBLE, SymbolType.DOUBLE, Double.parseDouble(dval)); + return new ParsedSymbol(yychar(), SymbolGroup.DOUBLE, SymbolType.DOUBLE, Double.parseDouble(dval)); } case 238: break; case 54: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.FILTER, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.FILTER, yytext()); } case 239: break; case 55: - { yybegin(XMLOPENTAG); + { startPos = yychar(); + yybegin(XMLOPENTAG); string.setLength(0); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTTAG_BEGIN, yytext()); + return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_STARTTAG_BEGIN, yytext()); } case 240: break; case 56: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.SHIFT_LEFT, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.SHIFT_LEFT, yytext()); } case 241: break; case 57: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.LOWER_EQUAL, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.LOWER_EQUAL, yytext()); } case 242: break; case 58: - { return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTVARTAG_BEGIN, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_STARTVARTAG_BEGIN, yytext()); } case 243: break; case 59: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NOT_EQUAL, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.NOT_EQUAL, yytext()); } case 244: break; case 60: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DECREMENT, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.DECREMENT, yytext()); } case 245: break; case 61: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_MINUS, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_MINUS, yytext()); } case 246: break; case 62: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.SHIFT_RIGHT, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.SHIFT_RIGHT, yytext()); } case 247: break; case 63: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.GREATER_EQUAL, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.GREATER_EQUAL, yytext()); } case 248: break; case 64: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NAMESPACE_OP, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.NAMESPACE_OP, yytext()); } case 249: break; case 65: @@ -1786,84 +1794,84 @@ public final class ActionScriptLexer { if (fval.endsWith("f")) { fval = fval.substring(0, fval.length() - 1); } - return new ParsedSymbol(SymbolGroup.FLOAT, SymbolType.FLOAT, Float.parseFloat(fval)); + return new ParsedSymbol(yychar(), SymbolGroup.FLOAT, SymbolType.FLOAT, Float.parseFloat(fval)); } case 250: break; case 66: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NULL_DOT, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.NULL_DOT, yytext()); } case 251: break; case 67: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NULL_COALESCE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.NULL_COALESCE, yytext()); } case 252: break; case 68: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.EQUALS, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.EQUALS, yytext()); } case 253: break; case 69: { try { - return new ParsedSymbol(SymbolGroup.INTEGER, SymbolType.INTEGER, Integer.parseInt(yytext(), 8)); + return new ParsedSymbol(yychar(), SymbolGroup.INTEGER, SymbolType.INTEGER, Integer.parseInt(yytext(), 8)); } catch (NumberFormatException nfe) { //its too long for an Integer var - return new ParsedSymbol(SymbolGroup.DOUBLE, SymbolType.DOUBLE, new BigInteger(yytext(), 8).doubleValue()); + return new ParsedSymbol(yychar(), SymbolGroup.DOUBLE, SymbolType.DOUBLE, new BigInteger(yytext(), 8).doubleValue()); } } case 254: break; case 70: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.DO, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.DO, yytext()); } case 255: break; case 71: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.AS, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.AS, yytext()); } case 256: break; case 72: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_PLUS, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_PLUS, yytext()); } case 257: break; case 73: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.INCREMENT, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.INCREMENT, yytext()); } case 258: break; case 74: - { return new ParsedSymbol(SymbolGroup.NAMESPACESUFFIX, SymbolType.NAMESPACESUFFIX, Integer.parseInt(yytext().substring(1))); + { return new ParsedSymbol(yychar(), SymbolGroup.NAMESPACESUFFIX, SymbolType.NAMESPACESUFFIX, Integer.parseInt(yytext().substring(1))); } case 259: break; case 75: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IF, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.IF, yytext()); } case 260: break; case 76: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.IS, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.IS, yytext()); } case 261: break; case 77: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IN, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.IN, yytext()); } case 262: break; case 78: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_BITAND, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_BITAND, yytext()); } case 263: break; case 79: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.AND, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.AND, yytext()); } case 264: break; case 80: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_BITOR, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_BITOR, yytext()); } case 265: break; case 81: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.OR, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.OR, yytext()); } case 266: break; case 82: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_XOR, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_XOR, yytext()); } case 267: break; case 83: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_MODULO, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_MODULO, yytext()); } case 268: break; case 84: @@ -1904,9 +1912,9 @@ public final class ActionScriptLexer { case 277: break; case 93: { yybegin(XML); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTFINISHTAG_END, yytext())); + pushback(new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_STARTFINISHTAG_END, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); @@ -1914,9 +1922,9 @@ public final class ActionScriptLexer { case 278: break; case 94: { yybegin(XMLOPENTAGATTRIB); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRIBUTENAME, yytext())); + pushback(new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_ATTRIBUTENAME, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); @@ -1924,12 +1932,12 @@ public final class ActionScriptLexer { case 279: break; case 95: { yybegin(XMLOPENTAG); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRIBUTEVALUE, yytext()); + return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_ATTRIBUTEVALUE, yytext()); } case 280: break; case 96: { yybegin(XMLOPENTAG); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_ATTRIBUTEVALUE_SINGLEQUOTED, yytext()); + return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_ATTRIBUTEVALUE_SINGLEQUOTED, yytext()); } case 281: break; case 97: @@ -1937,14 +1945,14 @@ public final class ActionScriptLexer { string.append(yytext()); String tos = string.toString(); string.setLength(0); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_INSTR, tos); + return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_INSTR, tos); } case 282: break; case 98: { yybegin(XMLOPENTAG); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTTAG_BEGIN, yytext())); + pushback(new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_STARTTAG_BEGIN, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); @@ -1952,9 +1960,9 @@ public final class ActionScriptLexer { case 283: break; case 99: { yybegin(YYINITIAL); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_STARTVARTAG_BEGIN, yytext())); + pushback(new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_STARTVARTAG_BEGIN, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); @@ -1993,90 +2001,90 @@ public final class ActionScriptLexer { } case 292: break; case 108: - { return new ParsedSymbol(SymbolGroup.REGEXP, SymbolType.REGEXP, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.REGEXP, SymbolType.REGEXP, yytext()); } case 293: break; case 109: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.REST, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.REST, yytext()); } case 294: break; case 110: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_SHIFT_LEFT, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_SHIFT_LEFT, yytext()); } case 295: break; case 111: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.STRICT_NOT_EQUAL, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.STRICT_NOT_EQUAL, yytext()); } case 296: break; case 112: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.USHIFT_RIGHT, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.USHIFT_RIGHT, yytext()); } case 297: break; case 113: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_SHIFT_RIGHT, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_SHIFT_RIGHT, yytext()); } case 298: break; case 114: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.STRICT_EQUALS, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.STRICT_EQUALS, yytext()); } case 299: break; case 115: { try { - return new ParsedSymbol(SymbolGroup.INTEGER, SymbolType.INTEGER, Integer.parseInt(yytext().substring(2), 16)); + return new ParsedSymbol(yychar(), SymbolGroup.INTEGER, SymbolType.INTEGER, Integer.parseInt(yytext().substring(2), 16)); } catch (NumberFormatException nfe) { //its too long for an Integer var - return new ParsedSymbol(SymbolGroup.DOUBLE, SymbolType.DOUBLE, new BigInteger(yytext().substring(2), 16).doubleValue()); + return new ParsedSymbol(yychar(), SymbolGroup.DOUBLE, SymbolType.DOUBLE, new BigInteger(yytext().substring(2), 16).doubleValue()); } } case 300: break; case 116: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.USE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.USE, yytext()); } case 301: break; case 117: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FOR, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.FOR, yytext()); } case 302: break; case 118: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.TRY, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.TRY, yytext()); } case 303: break; case 119: - { return new ParsedSymbol(SymbolGroup.PREPROCESSOR, SymbolType.PREPROCESSOR, yytext().substring(2)); + { return new ParsedSymbol(yychar(), SymbolGroup.PREPROCESSOR, SymbolType.PREPROCESSOR, yytext().substring(2)); } case 304: break; case 120: { String verbatimString = yytext(); verbatimString = verbatimString.substring(2, verbatimString.length() - 1); - return new ParsedSymbol(SymbolGroup.STRING, SymbolType.STRING, verbatimString); + return new ParsedSymbol(yychar(), SymbolGroup.STRING, SymbolType.STRING, verbatimString); } case 305: break; case 121: - { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.SET, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.SET, yytext()); } case 306: break; case 122: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.NEW, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.NEW, yytext()); } case 307: break; case 123: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.VAR, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.VAR, yytext()); } case 308: break; case 124: - { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.GET, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.GET, yytext()); } case 309: break; case 125: - { return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.NAN, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.GLOBALCONST, SymbolType.NAN, yytext()); } case 310: break; case 126: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_AND, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_AND, yytext()); } case 311: break; case 127: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_OR, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_OR, yytext()); } case 312: break; case 128: @@ -2084,7 +2092,7 @@ public final class ActionScriptLexer { yybegin(XML); String ret = string.toString(); string.setLength(0); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_CDATA, ret); + return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_CDATA, ret); } case 313: break; case 129: @@ -2092,14 +2100,14 @@ public final class ActionScriptLexer { yybegin(XML); String ret = string.toString(); string.setLength(0); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_COMMENT, ret); + return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_COMMENT, ret); } case 314: break; case 130: { yybegin(YYINITIAL); - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_FINISHVARTAG_BEGIN, yytext())); + pushback(new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_FINISHVARTAG_BEGIN, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); @@ -2111,7 +2119,7 @@ public final class ActionScriptLexer { String tos = string.toString(); string.setLength(0); string.append(yytext()); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, tos); + return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_TEXT, tos); } string.append(yytext()); } @@ -2121,7 +2129,7 @@ public final class ActionScriptLexer { yybegin(YYINITIAL); String ret = string.toString(); string.setLength(0); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_CDATA, ret); + return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_CDATA, ret); } case 317: break; case 133: @@ -2129,7 +2137,7 @@ public final class ActionScriptLexer { yybegin(YYINITIAL); String ret = string.toString(); string.setLength(0); - return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_COMMENT, ret); + return new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_COMMENT, ret); } case 318: break; case 134: @@ -2137,39 +2145,39 @@ public final class ActionScriptLexer { } case 319: break; case 135: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ASSIGN_USHIFT_RIGHT, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.ASSIGN_USHIFT_RIGHT, yytext()); } case 320: break; case 136: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CASE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.CASE, yytext()); } case 321: break; case 137: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.TRUE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.TRUE, yytext()); } case 322: break; case 138: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.THIS, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.THIS, yytext()); } case 323: break; case 139: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.ELSE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.ELSE, yytext()); } case 324: break; case 140: - { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.EACH, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.EACH, yytext()); } case 325: break; case 141: - { return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.NULL, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.GLOBALCONST, SymbolType.NULL, yytext()); } case 326: break; case 142: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.WITH, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.WITH, yytext()); } case 327: break; case 143: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.VOID, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.VOID, yytext()); } case 328: break; case 144: @@ -2178,9 +2186,9 @@ public final class ActionScriptLexer { } case 329: break; case 145: - { pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_FINISHTAG, yytext())); + { pushback(new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_FINISHTAG, yytext())); if (string.length() > 0){ - pushback(new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); + pushback(new ParsedSymbol(startPos, SymbolGroup.XML, SymbolType.XML_TEXT, string.toString())); string.setLength(0); } return lex(); @@ -2188,7 +2196,7 @@ public final class ActionScriptLexer { case 330: break; case 146: { String ret = string.toString(); string.setLength(0); string.append(yytext()); yybegin(XMLCOMMENT); - if (!ret.isEmpty()) return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, ret); + if (!ret.isEmpty()) return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_TEXT, ret); } case 331: break; case 147: @@ -2201,115 +2209,115 @@ public final class ActionScriptLexer { } case 333: break; case 149: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CLASS, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.CLASS, yytext()); } case 334: break; case 150: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CONST, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.CONST, yytext()); } case 335: break; case 151: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CATCH, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.CATCH, yytext()); } case 336: break; case 152: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FALSE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.FALSE, yytext()); } case 337: break; case 153: - { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.FINAL, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.FINAL, yytext()); } case 338: break; case 154: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.THROW, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.THROW, yytext()); } case 339: break; case 155: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.BREAK, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.BREAK, yytext()); } case 340: break; case 156: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.SUPER, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.SUPER, yytext()); } case 341: break; case 157: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.WHILE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.WHILE, yytext()); } case 342: break; case 158: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DELETE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.DELETE, yytext()); } case 343: break; case 159: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.TYPEOF, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.TYPEOF, yytext()); } case 344: break; case 160: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.RETURN, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.RETURN, yytext()); } case 345: break; case 161: - { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.STATIC, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.STATIC, yytext()); } case 346: break; case 162: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.SWITCH, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.SWITCH, yytext()); } case 347: break; case 163: - { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.NATIVE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.NATIVE, yytext()); } case 348: break; case 164: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IMPORT, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.IMPORT, yytext()); } case 349: break; case 165: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PUBLIC, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.PUBLIC, yytext()); } case 350: break; case 166: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.DEFAULT, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.DEFAULT, yytext()); } case 351: break; case 167: - { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.DYNAMIC, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.DYNAMIC, yytext()); } case 352: break; case 168: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FINALLY, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.FINALLY, yytext()); } case 353: break; case 169: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.EXTENDS, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.EXTENDS, yytext()); } case 354: break; case 170: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PACKAGE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.PACKAGE, yytext()); } case 355: break; case 171: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PRIVATE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.PRIVATE, yytext()); } case 356: break; case 172: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.CONTINUE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.CONTINUE, yytext()); } case 357: break; case 173: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.FUNCTION, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.FUNCTION, yytext()); } case 358: break; case 174: - { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.OVERRIDE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.OVERRIDE, yytext()); } case 359: break; case 175: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.INTERNAL, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.INTERNAL, yytext()); } case 360: break; case 176: - { return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.INFINITY, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.GLOBALCONST, SymbolType.INFINITY, yytext()); } case 361: break; case 177: @@ -2317,32 +2325,32 @@ public final class ActionScriptLexer { } case 362: break; case 178: - { return new ParsedSymbol(SymbolGroup.GLOBALCONST, SymbolType.UNDEFINED, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.GLOBALCONST, SymbolType.UNDEFINED, yytext()); } case 363: break; case 179: - { return new ParsedSymbol(SymbolGroup.IDENTIFIER, SymbolType.NAMESPACE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.IDENTIFIER, SymbolType.NAMESPACE, yytext()); } case 364: break; case 180: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.INTERFACE, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.INTERFACE, yytext()); } case 365: break; case 181: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.PROTECTED, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.PROTECTED, yytext()); } case 366: break; case 182: { String ret = string.toString(); string.setLength(0); string.append(yytext() ); yybegin(XMLCDATA); - if (!ret.isEmpty()) return new ParsedSymbol(SymbolGroup.XML, SymbolType.XML_TEXT, ret); + if (!ret.isEmpty()) return new ParsedSymbol(yychar(), SymbolGroup.XML, SymbolType.XML_TEXT, ret); } case 367: break; case 183: - { return new ParsedSymbol(SymbolGroup.KEYWORD, SymbolType.IMPLEMENTS, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.KEYWORD, SymbolType.IMPLEMENTS, yytext()); } case 368: break; case 184: - { return new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.INSTANCEOF, yytext()); + { return new ParsedSymbol(yychar(), SymbolGroup.OPERATOR, SymbolType.INSTANCEOF, yytext()); } case 369: break; case 185: @@ -2356,14 +2364,14 @@ public final class ActionScriptLexer { } fvalues[i] = Float.parseFloat(fval); } - return new ParsedSymbol(SymbolGroup.FLOAT4, SymbolType.FLOAT4, new Float4(fvalues)); + return new ParsedSymbol(yychar(), SymbolGroup.FLOAT4, SymbolType.FLOAT4, new Float4(fvalues)); } case 370: break; default: if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { zzAtEOF = true; { - return new ParsedSymbol(SymbolGroup.EOF, SymbolType.EOF, null); + return new ParsedSymbol(yychar(), SymbolGroup.EOF, SymbolType.EOF, null); } } else { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ParsedSymbol.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ParsedSymbol.java index 6d4607bb6..55b421a92 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ParsedSymbol.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ParsedSymbol.java @@ -37,13 +37,20 @@ public class ParsedSymbol { * Type */ public SymbolType type; + + /** + * Position in source text + */ + public int position; /** * Constructor. + * @param position Position * @param group Group * @param type Type */ - public ParsedSymbol(SymbolGroup group, SymbolType type) { + public ParsedSymbol(int position, SymbolGroup group, SymbolType type) { + this.position = position; this.group = group; this.type = type; this.value = null; @@ -51,11 +58,13 @@ public class ParsedSymbol { /** * Constructor. + * @param position Position * @param group Group * @param type Type * @param value Value */ - public ParsedSymbol(SymbolGroup group, SymbolType type, Object value) { + public ParsedSymbol(int position, SymbolGroup group, SymbolType type, Object value) { + this.position = position; this.group = group; this.type = type; this.value = value; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/ActionScript2VariableParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2SimpleParser.java similarity index 85% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/ActionScript2VariableParser.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2SimpleParser.java index 453a15973..b65eaa28d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/ActionScript2VariableParser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2SimpleParser.java @@ -14,21 +14,26 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library. */ -package com.jpexs.decompiler.flash.action.parser.script.variables; +package com.jpexs.decompiler.flash.action.parser.script; +import com.jpexs.decompiler.flash.simpleparser.Variable; +import com.jpexs.decompiler.flash.simpleparser.SimpleParseException; +import com.jpexs.decompiler.flash.simpleparser.Type; +import com.jpexs.decompiler.flash.simpleparser.Scope; +import com.jpexs.decompiler.flash.simpleparser.CatchScope; +import com.jpexs.decompiler.flash.simpleparser.ClassScope; +import com.jpexs.decompiler.flash.simpleparser.VariableOrScope; +import com.jpexs.decompiler.flash.simpleparser.FunctionScope; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.action.parser.ActionParseException; -import com.jpexs.decompiler.flash.action.parser.script.ActionScriptLexer; -import com.jpexs.decompiler.flash.action.parser.script.LexBufferer; -import com.jpexs.decompiler.flash.action.parser.script.ParsedSymbol; -import com.jpexs.decompiler.flash.action.parser.script.SymbolGroup; -import com.jpexs.decompiler.flash.action.parser.script.SymbolType; +import com.jpexs.decompiler.flash.simpleparser.SimpleParser; import com.jpexs.decompiler.flash.types.CLIPACTIONRECORD; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.helpers.CancellableWorker; import com.jpexs.helpers.Reference; import java.io.IOException; import java.io.StringReader; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; @@ -40,25 +45,25 @@ import java.util.Map; * * @author JPEXS */ -public class ActionScript2VariableParser { +public class ActionScript2SimpleParser implements SimpleParser { /** * Swf version */ private final int swfVersion; - + /** * Constructor * * @param swf Swf */ - public ActionScript2VariableParser(SWF swf) { + public ActionScript2SimpleParser(SWF swf) { this.swfVersion = swf.version; } private final boolean debugMode = false; - private void commands(List errors, boolean inFunction, boolean inMethod, int forinlevel, boolean inTellTarget, List variables, Reference hasEval) throws IOException, InterruptedException, ActionParseException { + private void commands(List errors, boolean inFunction, boolean inMethod, int forinlevel, boolean inTellTarget, List variables, Reference hasEval) throws IOException, InterruptedException, SimpleParseException, ActionParseException { if (debugMode) { System.out.println("commands:"); } @@ -70,7 +75,7 @@ public class ActionScript2VariableParser { } } - private String type(List errors, boolean definition, List variables) throws IOException, InterruptedException, ActionParseException { + private String type(List errors, boolean definition, List variables) throws IOException, InterruptedException, SimpleParseException, ActionParseException { ParsedSymbol s = lex(); if (!expectedIdentifier(errors, s, lexer.yyline())) { return null; @@ -96,7 +101,7 @@ public class ActionScript2VariableParser { return ret; } - private boolean expected(List errors, ParsedSymbol symb, int line, Object... expected) throws IOException { + private boolean expected(List errors, ParsedSymbol symb, int line, Object... expected) throws IOException { boolean found = false; for (Object t : expected) { if (symb.type == t) { @@ -116,13 +121,13 @@ public class ActionScript2VariableParser { expStr += e; first = false; } - errors.add(new ActionVariableParseException("" + expStr + " expected but " + symb.type + " found", line, symb.position)); + errors.add(new SimpleParseException("" + expStr + " expected but " + symb.type + " found", line, symb.position)); return false; } return true; } - private ParsedSymbol expectedType(List errors, Object... type) throws IOException, InterruptedException, ActionParseException { + private ParsedSymbol expectedType(List errors, Object... type) throws IOException, InterruptedException, SimpleParseException, ActionParseException { ParsedSymbol symb = lex(); if (!expected(errors, symb, lexer.yyline(), type)) { return null; @@ -130,7 +135,7 @@ public class ActionScript2VariableParser { return symb; } - private ParsedSymbol lex() throws IOException, InterruptedException, ActionParseException { + private ParsedSymbol lex() throws IOException, InterruptedException, SimpleParseException, ActionParseException, ActionParseException { if (CancellableWorker.isInterrupted()) { throw new InterruptedException(); } @@ -141,7 +146,7 @@ public class ActionScript2VariableParser { return ret; } - private List call(List errors, boolean inFunction, boolean inMethod, boolean inTellTarget, List variables, Reference hasEval) throws IOException, InterruptedException, ActionParseException { + private List call(List errors, boolean inFunction, boolean inMethod, boolean inTellTarget, List variables, Reference hasEval) throws IOException, InterruptedException, SimpleParseException, ActionParseException { List ret = new ArrayList<>(); ParsedSymbol s = lex(); while (s.type != SymbolType.PARENT_CLOSE) { @@ -155,7 +160,7 @@ public class ActionScript2VariableParser { return ret; } - private void function(List errors, boolean withBody, String functionName, int functionNamePosition, boolean isMethod, List variables, boolean inTellTarget, Reference hasEval) throws IOException, InterruptedException, ActionParseException { + private void function(List errors, boolean withBody, String functionName, int functionNamePosition, boolean isMethod, List variables, boolean inTellTarget, Reference hasEval) throws IOException, InterruptedException, SimpleParseException, ActionParseException { ParsedSymbol s; expectedType(errors, SymbolType.PARENT_OPEN); s = lex(); @@ -205,7 +210,7 @@ public class ActionScript2VariableParser { variables.add(new FunctionScope(subvariables)); } - private boolean traits(List errors, boolean isInterface, String className, List variables, boolean inTellTarget, Reference hasEval) throws IOException, InterruptedException, ActionParseException { + private boolean traits(List errors, boolean isInterface, String className, List variables, boolean inTellTarget, Reference hasEval) throws IOException, InterruptedException, SimpleParseException, ActionParseException { ParsedSymbol s; @@ -263,7 +268,7 @@ public class ActionScript2VariableParser { return true; } - private boolean expressionCommands(List errors, ParsedSymbol s, boolean inFunction, boolean inMethod, boolean inTellTarget, List variables, Reference hasEval) throws IOException, InterruptedException, ActionParseException { + private boolean expressionCommands(List errors, ParsedSymbol s, boolean inFunction, boolean inMethod, boolean inTellTarget, List variables, Reference hasEval) throws IOException, InterruptedException, SimpleParseException, ActionParseException { if (debugMode) { System.out.println("expressionCommands:"); } @@ -383,7 +388,7 @@ public class ActionScript2VariableParser { } else if (s.value.equals("POST")) { //empty } else { - errors.add(new ActionVariableParseException("Invalid method, \"GET\" or \"POST\" expected.", lexer.yyline(), s.position)); + errors.add(new SimpleParseException("Invalid method, \"GET\" or \"POST\" expected.", lexer.yyline(), s.position)); } } else { lexer.pushback(s); @@ -481,7 +486,7 @@ public class ActionScript2VariableParser { } else if (s.value.equals("GET")) { //empty } else { - errors.add(new ActionVariableParseException("Invalid method, \"GET\" or \"POST\" expected.", lexer.yyline(), s.position)); + errors.add(new SimpleParseException("Invalid method, \"GET\" or \"POST\" expected.", lexer.yyline(), s.position)); } } else { lexer.pushback(s); @@ -674,20 +679,20 @@ public class ActionScript2VariableParser { SymbolType.NUMBER_OP, SymbolType.STRING_OP); } - private boolean expectedIdentifier(List errors, ParsedSymbol s, int line, Object... exceptions) throws IOException { + private boolean expectedIdentifier(List errors, ParsedSymbol s, int line, Object... exceptions) throws IOException { for (Object ex : exceptions) { if (s.isType(ex)) { return true; } } if (!isIdentifier(s)) { - errors.add(new ActionVariableParseException(SymbolType.IDENTIFIER + " expected but " + s.type + " found", line, s.position)); + errors.add(new SimpleParseException(SymbolType.IDENTIFIER + " expected but " + s.type + " found", line, s.position)); return false; } return true; } - private boolean command(List errors, boolean inFunction, boolean inMethod, int forinlevel, boolean inTellTarget, List variables, Reference hasEval) throws IOException, InterruptedException, ActionParseException { + private boolean command(List errors, boolean inFunction, boolean inMethod, int forinlevel, boolean inTellTarget, List variables, Reference hasEval) throws IOException, InterruptedException, SimpleParseException, ActionParseException { LexBufferer buf = new LexBufferer(); lexer.addListener(buf); if (debugMode) { @@ -791,7 +796,7 @@ public class ActionScript2VariableParser { break; case FUNCTION: s = lexer.lex(); - if (expectedIdentifier(errors, s, lexer.yyline())) { + if (expectedIdentifier(errors, s, lexer.yyline())) { function(errors, true, s.value.toString(), s.position, false, variables, inTellTarget, hasEval); } break; @@ -1004,7 +1009,7 @@ public class ActionScript2VariableParser { ret = true; break; default: - errors.add(new ActionVariableParseException("Unknown directive: #" + s.value, lexer.yyline(), s.position)); + errors.add(new SimpleParseException("Unknown directive: #" + s.value, lexer.yyline(), s.position)); } break; default: @@ -1023,11 +1028,11 @@ public class ActionScript2VariableParser { if ((s != null) && (s.type != SymbolType.SEMICOLON)) { lexer.pushback(s); } - + return ret; } - private boolean expression(List errors, boolean inFunction, boolean inMethod, boolean inTellTarget, boolean allowRemainder, List variables, boolean allowComma, Reference hasEval) throws IOException, InterruptedException, ActionParseException { + private boolean expression(List errors, boolean inFunction, boolean inMethod, boolean inTellTarget, boolean allowRemainder, List variables, boolean allowComma, Reference hasEval) throws IOException, InterruptedException, SimpleParseException, ActionParseException { if (debugMode) { System.out.println("expression:"); } @@ -1049,7 +1054,7 @@ public class ActionScript2VariableParser { return true; } - private ParsedSymbol peekLex() throws IOException, InterruptedException, ActionParseException { + private ParsedSymbol peekLex() throws IOException, InterruptedException, SimpleParseException, ActionParseException { ParsedSymbol lookahead = lex(); lexer.pushback(lookahead); return lookahead; @@ -1082,7 +1087,7 @@ public class ActionScript2VariableParser { return s.type.getPrecedence(); } - private boolean expression1(List errors, boolean lhs, int min_precedence, boolean inFunction, boolean inMethod, boolean inTellTarget, boolean allowRemainder, List variables, Reference hasEval) throws IOException, InterruptedException, ActionParseException { + private boolean expression1(List errors, boolean lhs, int min_precedence, boolean inFunction, boolean inMethod, boolean inTellTarget, boolean allowRemainder, List variables, Reference hasEval) throws IOException, InterruptedException, SimpleParseException, ActionParseException { ParsedSymbol op; boolean rhs; ParsedSymbol lookahead = peekLex(); @@ -1185,7 +1190,7 @@ public class ActionScript2VariableParser { return lhs; } - private int brackets(List errors, boolean inFunction, boolean inMethod, boolean inTellTarget, List variables, Reference hasEval) throws IOException, InterruptedException, ActionParseException { + private int brackets(List errors, boolean inFunction, boolean inMethod, boolean inTellTarget, List variables, Reference hasEval) throws IOException, InterruptedException, SimpleParseException, ActionParseException { ParsedSymbol s = lex(); int arrCnt = 0; if (s.type == SymbolType.BRACKET_OPEN) { @@ -1209,7 +1214,7 @@ public class ActionScript2VariableParser { return arrCnt; } - private boolean handleVariable(List errors, ParsedSymbol s, boolean ret, List variables, Reference allowMemberOrCall, boolean inFunction, boolean inMethod, boolean inTellTarget, Reference hasEval) throws IOException, InterruptedException, ActionParseException { + private boolean handleVariable(List errors, ParsedSymbol s, boolean ret, List variables, Reference allowMemberOrCall, boolean inFunction, boolean inMethod, boolean inTellTarget, Reference hasEval) throws IOException, InterruptedException, SimpleParseException, ActionParseException { if (s.value.equals("not")) { expressionPrimary(errors, inFunction, inMethod, inTellTarget, false, variables, true, hasEval); ret = true; @@ -1256,7 +1261,7 @@ public class ActionScript2VariableParser { return ret; } - private boolean expressionPrimary(List errors, boolean inFunction, boolean inMethod, boolean inTellTarget, boolean allowRemainder, List variables, boolean allowCall, Reference hasEval) throws IOException, InterruptedException, ActionParseException { + private boolean expressionPrimary(List errors, boolean inFunction, boolean inMethod, boolean inTellTarget, boolean allowRemainder, List variables, boolean allowCall, Reference hasEval) throws IOException, InterruptedException, SimpleParseException, ActionParseException { if (debugMode) { System.out.println("primary:"); } @@ -1303,7 +1308,7 @@ public class ActionScript2VariableParser { //errors.add(new ActionVariableParseException("Compiling §§" + s.value + " is not available, sorry", lexer.yyline())); break; default: - errors.add(new ActionVariableParseException("Unknown preprocessor instruction: §§" + s.value, lexer.yyline(), s.position)); + errors.add(new SimpleParseException("Unknown preprocessor instruction: §§" + s.value, lexer.yyline(), s.position)); } expectedType(errors, SymbolType.PARENT_CLOSE); @@ -1415,7 +1420,7 @@ public class ActionScript2VariableParser { case PARENT_OPEN: boolean pexpr = expression(errors, inFunction, inMethod, inTellTarget, true, variables, true, hasEval); if (!pexpr) { - errors.add(new ActionVariableParseException("Expression expected", lexer.yyline(), s.position)); + errors.add(new SimpleParseException("Expression expected", lexer.yyline(), s.position)); } expectedType(errors, SymbolType.PARENT_CLOSE); allowMemberOrCall = true; @@ -1490,7 +1495,7 @@ public class ActionScript2VariableParser { return ret; } - private boolean memberOrCall(List errors, boolean ret, boolean inFunction, boolean inMethod, boolean inTellTarget, List variables, boolean allowCall, Reference hasEval) throws IOException, InterruptedException, ActionParseException { + private boolean memberOrCall(List errors, boolean ret, boolean inFunction, boolean inMethod, boolean inTellTarget, List variables, boolean allowCall, Reference hasEval) throws IOException, InterruptedException, SimpleParseException, ActionParseException { ParsedSymbol op = lex(); while (op.isType(SymbolType.PARENT_OPEN, SymbolType.BRACKET_OPEN, SymbolType.DOT)) { if (op.type == SymbolType.PARENT_OPEN) { @@ -1531,108 +1536,106 @@ public class ActionScript2VariableParser { private ActionScriptLexer lexer = null; - /** - * Convert a string to a high-level model. - * - * @param str The string to convert - * @throws ActionParseException On parse error - * @throws IOException On I/O error - * @throws InterruptedException On interrupt - */ + + @Override public void parse( - String str, + String str, Map> definitionPosToReferences, Map referenceToDefinition, - List errors - ) throws ActionParseException, IOException, InterruptedException { - lexer = new ActionScriptLexer(new StringReader(str)); - if (swfVersion >= ActionScriptLexer.SWF_VERSION_CASE_SENSITIVE) { - lexer.setCaseSensitiveIdentifiers(true); - } - - ParsedSymbol symb = lexer.lex(); - boolean inOnHandler = false; - - if (symb.type == SymbolType.IDENTIFIER && ("on".equals(symb.value) || "onClipEvent".equals(symb.value))) { - expectedType(errors, SymbolType.PARENT_OPEN); - symb = lexer.lex(); - boolean condEmpty = true; - while (symb.type == SymbolType.IDENTIFIER) { - condEmpty = false; - switch ((String) symb.value) { - case "press": - break; - case "release": - break; - case "releaseOutside": - break; - case "rollOver": - break; - case "rollOut": - break; - case "dragOut": - break; - case "dragOver": - break; - case "keyPress": - symb = lexer.lex(); - expected(errors, symb, lexer.yyline(), SymbolType.STRING); - Integer key = CLIPACTIONRECORD.stringToKey((String) symb.value); - if (key == null) { - errors.add(new ActionVariableParseException("Invalid key", lexer.yyline(), symb.position)); - } - break; - case "keyUp": - break; - case "keyDown": - break; - case "mouseUp": - break; - case "mouseDown": - break; - case "mouseMove": - break; - case "unload": - break; - case "enterFrame": - break; - case "load": - break; - case "data": - break; - default: - errors.add(new ActionVariableParseException("Unrecognized event type", lexer.yyline(), symb.position)); - } - symb = lexer.lex(); - if (symb.type == SymbolType.PARENT_CLOSE) { - break; - } - expected(errors, symb, lexer.yyline(), SymbolType.COMMA); - symb = lexer.lex(); + List errors + ) throws SimpleParseException, IOException, InterruptedException { + try { + lexer = new ActionScriptLexer(new StringReader(str)); + if (swfVersion >= ActionScriptLexer.SWF_VERSION_CASE_SENSITIVE) { + lexer.setCaseSensitiveIdentifiers(true); } - expected(errors, symb, lexer.yyline(), SymbolType.PARENT_CLOSE); - if (condEmpty) { - errors.add(new ActionVariableParseException("condition must be non empty", lexer.yyline(), symb.position)); + + ParsedSymbol symb = lexer.lex(); + boolean inOnHandler = false; + + if (symb.type == SymbolType.IDENTIFIER && ("on".equals(symb.value) || "onClipEvent".equals(symb.value))) { + expectedType(errors, SymbolType.PARENT_OPEN); + symb = lexer.lex(); + boolean condEmpty = true; + while (symb.type == SymbolType.IDENTIFIER) { + condEmpty = false; + switch ((String) symb.value) { + case "press": + break; + case "release": + break; + case "releaseOutside": + break; + case "rollOver": + break; + case "rollOut": + break; + case "dragOut": + break; + case "dragOver": + break; + case "keyPress": + symb = lexer.lex(); + expected(errors, symb, lexer.yyline(), SymbolType.STRING); + Integer key = CLIPACTIONRECORD.stringToKey((String) symb.value); + if (key == null) { + errors.add(new SimpleParseException("Invalid key", lexer.yyline(), symb.position)); + } + break; + case "keyUp": + break; + case "keyDown": + break; + case "mouseUp": + break; + case "mouseDown": + break; + case "mouseMove": + break; + case "unload": + break; + case "enterFrame": + break; + case "load": + break; + case "data": + break; + default: + errors.add(new SimpleParseException("Unrecognized event type", lexer.yyline(), symb.position)); + } + symb = lexer.lex(); + if (symb.type == SymbolType.PARENT_CLOSE) { + break; + } + expected(errors, symb, lexer.yyline(), SymbolType.COMMA); + symb = lexer.lex(); + } + expected(errors, symb, lexer.yyline(), SymbolType.PARENT_CLOSE); + if (condEmpty) { + errors.add(new SimpleParseException("condition must be non empty", lexer.yyline(), symb.position)); + } + expectedType(errors, SymbolType.CURLY_OPEN); + inOnHandler = true; + } else { + lexer.pushback(symb); } - expectedType(errors, SymbolType.CURLY_OPEN); - inOnHandler = true; - } else { - lexer.pushback(symb); - } - List vars = new ArrayList<>(); - Reference hasEval = new Reference<>(false); - commands(errors, false, false, 0, false, vars, hasEval); - Map varNameToDefinitionPosition = new LinkedHashMap<>(); + List vars = new ArrayList<>(); + Reference hasEval = new Reference<>(false); + commands(errors, false, false, 0, false, vars, hasEval); + Map varNameToDefinitionPosition = new LinkedHashMap<>(); - parseVariablesList(new ArrayList<>(), vars, definitionPosToReferences, referenceToDefinition, varNameToDefinitionPosition); + parseVariablesList(new ArrayList<>(), vars, definitionPosToReferences, referenceToDefinition, varNameToDefinitionPosition); - if (inOnHandler) { - expectedType(errors, SymbolType.CURLY_CLOSE); - } + if (inOnHandler) { + expectedType(errors, SymbolType.CURLY_CLOSE); + } - if (lexer.lex().type != SymbolType.EOF) { - errors.add(new ActionVariableParseException("Parsing finished before end of the file", lexer.yyline(), lexer.yychar())); + if (lexer.lex().type != SymbolType.EOF) { + errors.add(new SimpleParseException("Parsing finished before end of the file", lexer.yyline(), lexer.yychar())); + } + } catch (ActionParseException ex) { + errors.add(new SimpleParseException(ex.getMessage(), ex.line, ex.position)); } } @@ -1699,19 +1702,19 @@ public class ActionScript2VariableParser { } } - private void versionRequired(List errors, ParsedSymbol s, int min) throws ActionParseException { + private void versionRequired(List errors, ParsedSymbol s, int min) throws SimpleParseException { versionRequired(errors, s.value.toString(), min, Integer.MAX_VALUE, s.position); } - private void versionRequired(List errors, String type, int min, int max, long position) throws ActionParseException { + private void versionRequired(List errors, String type, int min, int max, long position) throws SimpleParseException { if (min == max && swfVersion != min) { - errors.add(new ActionVariableParseException(type + " requires SWF version " + min, lexer.yyline(), position)); + errors.add(new SimpleParseException(type + " requires SWF version " + min, lexer.yyline(), position)); } if (swfVersion < min) { - errors.add(new ActionVariableParseException(type + " requires at least SWF version " + min, lexer.yyline(), position)); + errors.add(new SimpleParseException(type + " requires at least SWF version " + min, lexer.yyline(), position)); } if (swfVersion > max) { - errors.add(new ActionVariableParseException(type + " requires SWF version lower than " + max, lexer.yyline(), position)); + errors.add(new SimpleParseException(type + " requires SWF version lower than " + max, lexer.yyline(), position)); } } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/CatchScope.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/CatchScope.java similarity index 95% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/CatchScope.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/CatchScope.java index f447b528e..e106805fd 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/CatchScope.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/CatchScope.java @@ -14,7 +14,7 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library. */ -package com.jpexs.decompiler.flash.action.parser.script.variables; +package com.jpexs.decompiler.flash.simpleparser; import java.util.ArrayList; import java.util.List; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/ClassScope.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/ClassScope.java similarity index 94% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/ClassScope.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/ClassScope.java index 0b935d394..6f31fe29c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/ClassScope.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/ClassScope.java @@ -14,7 +14,7 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library. */ -package com.jpexs.decompiler.flash.action.parser.script.variables; +package com.jpexs.decompiler.flash.simpleparser; import java.util.ArrayList; import java.util.List; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/FunctionScope.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/FunctionScope.java similarity index 94% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/FunctionScope.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/FunctionScope.java index d33c66c9a..118f02d12 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/FunctionScope.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/FunctionScope.java @@ -14,7 +14,7 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library. */ -package com.jpexs.decompiler.flash.action.parser.script.variables; +package com.jpexs.decompiler.flash.simpleparser; import java.util.ArrayList; import java.util.List; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/Scope.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/Scope.java similarity index 93% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/Scope.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/Scope.java index 2f8de129f..3f12fe057 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/Scope.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/Scope.java @@ -14,7 +14,7 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library. */ -package com.jpexs.decompiler.flash.action.parser.script.variables; +package com.jpexs.decompiler.flash.simpleparser; import java.util.List; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/ActionVariableParseException.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParseException.java similarity index 79% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/ActionVariableParseException.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParseException.java index 869ed7e46..b59a146dc 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/ActionVariableParseException.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParseException.java @@ -14,23 +14,23 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library. */ -package com.jpexs.decompiler.flash.action.parser.script.variables; +package com.jpexs.decompiler.flash.simpleparser; import com.jpexs.decompiler.flash.ParseException; /** - * Exception for action parsing errors + * Exception for Simple parsing errors * * @author JPEXS */ -public class ActionVariableParseException extends ParseException { +public class SimpleParseException extends ParseException { /** * Constructs a new parse exception. * @param text Text of the exception * @param line Line number where the exception occurred */ - public ActionVariableParseException(String text, long line) { + public SimpleParseException(String text, long line) { super(text, line); } @@ -40,7 +40,7 @@ public class ActionVariableParseException extends ParseException { * @param line Line number where the exception occurred * @param position Position where the exception occured */ - public ActionVariableParseException(String text, long line, long position) { + public SimpleParseException(String text, long line, long position) { super(text, line, position); } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParser.java new file mode 100644 index 000000000..4357976ce --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParser.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2010-2025 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.simpleparser; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * + * @author JPEXS + */ +public interface SimpleParser { + + /** + * Parses document. + * + * @param str The string to convert + * @param definitionPosToReferences Definition position to references + * @param referenceToDefinition Reference to definition + * @param errors Errors + * @throws SimpleParseException On parse error + * @throws IOException On I/O error + * @throws InterruptedException On interrupt + */ + public void parse( + String str, + Map> definitionPosToReferences, + Map referenceToDefinition, + List errors + ) throws SimpleParseException, IOException, InterruptedException; +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/Type.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/Type.java similarity index 92% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/Type.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/Type.java index 88279c65c..65ceef494 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/Type.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/Type.java @@ -14,7 +14,7 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library. */ -package com.jpexs.decompiler.flash.action.parser.script.variables; +package com.jpexs.decompiler.flash.simpleparser; /** * diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/Variable.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/Variable.java similarity index 94% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/Variable.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/Variable.java index eceb65cf6..a68190206 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/Variable.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/Variable.java @@ -14,7 +14,7 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library. */ -package com.jpexs.decompiler.flash.action.parser.script.variables; +package com.jpexs.decompiler.flash.simpleparser; /** * diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/VariableOrScope.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/VariableOrScope.java similarity index 91% rename from libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/VariableOrScope.java rename to libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/VariableOrScope.java index b7297a8dc..9ec9040e4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/variables/VariableOrScope.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/VariableOrScope.java @@ -14,7 +14,7 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library. */ -package com.jpexs.decompiler.flash.action.parser.script.variables; +package com.jpexs.decompiler.flash.simpleparser; /** * diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java index c1d5f741d..4a30b4a20 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java @@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.abc.ScriptPack; import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions; +import com.jpexs.decompiler.flash.abc.avm2.parser.script.ActionScript3SimpleParser; import com.jpexs.decompiler.flash.abc.types.ABCException; import com.jpexs.decompiler.flash.abc.types.MethodBody; import com.jpexs.decompiler.flash.abc.types.MethodInfo; @@ -65,6 +66,7 @@ import com.jpexs.decompiler.flash.gui.View; import com.jpexs.decompiler.flash.gui.ViewMessages; import com.jpexs.decompiler.flash.gui.controls.JPersistentSplitPane; import com.jpexs.decompiler.flash.gui.editor.LinkHandler; +import com.jpexs.decompiler.flash.gui.editor.VariableMarker; import com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTree; import com.jpexs.decompiler.flash.gui.tagtree.AbstractTagTreeModel; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; @@ -140,6 +142,7 @@ import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.text.Highlighter; import javax.swing.tree.TreePath; +import jsyntaxpane.DefaultSyntaxKit; import jsyntaxpane.Token; import jsyntaxpane.TokenType; @@ -249,6 +252,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener(); @@ -1047,8 +1051,8 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener 0) { try { @@ -1018,7 +1013,7 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL } } - scriptLoaded = true; + scriptLoaded = true; fireScript(); } @@ -1079,9 +1074,9 @@ public class DecompiledEditorPane extends DebuggableEditorPane implements CaretL } setCaretPosition(position); } - + @Override public synchronized void setCaretPosition(int position) { super.setCaretPosition(position); - } + } } diff --git a/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java b/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java index 417d9582f..aa3ff0a70 100644 --- a/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java @@ -16,9 +16,11 @@ */ package com.jpexs.decompiler.flash.gui.action; +import com.jpexs.decompiler.flash.gui.editor.VariableMarker; import com.jpexs.decompiler.flash.DisassemblyListener; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.ValueTooLargeException; +import com.jpexs.decompiler.flash.abc.avm2.parser.script.ActionScript3SimpleParser; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionGraph; import com.jpexs.decompiler.flash.action.ActionList; @@ -29,6 +31,7 @@ import com.jpexs.decompiler.flash.action.parser.pcode.ASMParsedSymbol; import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser; import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer; import com.jpexs.decompiler.flash.action.parser.script.ActionScript2Parser; +import com.jpexs.decompiler.flash.action.parser.script.ActionScript2SimpleParser; import com.jpexs.decompiler.flash.action.parser.script.ActionScriptLexer; import com.jpexs.decompiler.flash.action.parser.script.ParsedSymbol; import com.jpexs.decompiler.flash.action.parser.script.SymbolType; @@ -637,7 +640,7 @@ public class ActionPanel extends JPanel implements SearchListener swfRef = new WeakReference(null); public DebuggableEditorPane() { @@ -91,14 +90,6 @@ public class DebuggableEditorPane extends LineMarkedEditorPane implements BreakP BREAKPOINT_MARKER = new LineMarker(FG_BREAKPOINT_COLOR, BG_BREAKPOINT_COLOR, PRIORITY_BREAKPOINT); } } - - public void setSwf(SWF swf) { - this.swfRef = new WeakReference<>(swf); - } - - public SWF getSwf() { - return swfRef.get(); - } public synchronized void setScriptName(String scriptName, String breakPointScriptName) { this.scriptName = scriptName; diff --git a/src/com/jpexs/decompiler/flash/gui/editor/LineMarkedEditorPane.java b/src/com/jpexs/decompiler/flash/gui/editor/LineMarkedEditorPane.java index b342eda20..2d5b63c62 100644 --- a/src/com/jpexs/decompiler/flash/gui/editor/LineMarkedEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/editor/LineMarkedEditorPane.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.gui.editor; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.gui.AppStrings; +import com.jpexs.decompiler.flash.simpleparser.SimpleParser; import com.jpexs.helpers.Reference; import java.awt.Color; import java.awt.Cursor; @@ -80,7 +81,9 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan private LinkHandler linkHandler = this; private Point lastCursorPos = new Point(0, 0); - + + private SimpleParser parser; + public static class LineMarker implements Comparable { private final Color bgColor; @@ -147,6 +150,15 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan } } + public SimpleParser getParser() { + return parser; + } + + public void setParser(SimpleParser parser) { + this.parser = parser; + } + + private Map> lineMarkers = Collections.synchronizedMap(new HashMap>()); public void setLineMarkers(Map> colorMarkers) { diff --git a/src/com/jpexs/decompiler/flash/gui/action/ActionVariableMarker.java b/src/com/jpexs/decompiler/flash/gui/editor/VariableMarker.java similarity index 89% rename from src/com/jpexs/decompiler/flash/gui/action/ActionVariableMarker.java rename to src/com/jpexs/decompiler/flash/gui/editor/VariableMarker.java index 8807f52db..7fdd02988 100644 --- a/src/com/jpexs/decompiler/flash/gui/action/ActionVariableMarker.java +++ b/src/com/jpexs/decompiler/flash/gui/editor/VariableMarker.java @@ -14,18 +14,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.jpexs.decompiler.flash.gui.action; +package com.jpexs.decompiler.flash.gui.editor; -import com.jpexs.decompiler.flash.SWF; -import com.jpexs.decompiler.flash.action.parser.ActionParseException; -import com.jpexs.decompiler.flash.action.parser.script.variables.ActionScript2VariableParser; -import com.jpexs.decompiler.flash.action.parser.script.variables.ActionVariableParseException; -import com.jpexs.decompiler.flash.gui.editor.DebuggableEditorPane; -import com.jpexs.decompiler.flash.gui.editor.LineMarkedEditorPane; -import com.jpexs.decompiler.flash.gui.editor.LinkHandler; -import com.jpexs.decompiler.flash.gui.editor.ScrollbarOverlay; -import com.jpexs.decompiler.flash.gui.editor.TrackRectSubstanceScrollbarUI; -import com.jpexs.decompiler.flash.gui.editor.WavyUnderLinePainter; +import com.jpexs.decompiler.flash.simpleparser.SimpleParseException; +import com.jpexs.decompiler.flash.simpleparser.SimpleParser; import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.MouseEvent; @@ -41,7 +33,6 @@ import java.util.Map; import java.util.Set; import java.util.Timer; import java.util.TimerTask; -import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JEditorPane; import javax.swing.JLayer; @@ -69,9 +60,9 @@ import jsyntaxpane.util.Configuration; import org.pushingpixels.substance.internal.ui.SubstanceScrollBarUI; /** - * This class highlights Variable tokens of ActionScript 1/2 + * This class highlights Variable and error tokens. */ -public class ActionVariableMarker implements SyntaxComponent, CaretListener, PropertyChangeListener, DocumentListener, LinkHandler { +public class VariableMarker implements SyntaxComponent, CaretListener, PropertyChangeListener, DocumentListener, LinkHandler { public static final String DEFAULT_TOKENTYPES = "IDENTIFIER, KEYWORD, REGEX"; public static final String PROPERTY_COLOR = "ActionVariableMarker.Color"; @@ -88,8 +79,6 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro private Markers.SimpleMarker errorMarker; private Status status; private Map errors = new LinkedHashMap<>(); - private boolean errorsShown = false; - public static final long ERROR_DELAY = 2000; private Timer errorsTimer; @@ -109,7 +98,7 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro /** * Constructs a new Token highlighter */ - public ActionVariableMarker() { + public VariableMarker() { } @Override @@ -145,7 +134,6 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro public void removeErrorMarkers() { Markers.removeMarkers(pane, errorMarker); - errorsShown = false; scrollbarOverlay.removeMarkers(SCROLLBAR_ERROR_COLOR); } @@ -206,7 +194,6 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro } layer.repaint(); doc.readUnlock(); - errorsShown = true; } /** @@ -348,7 +335,7 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro scrollPane.getVerticalScrollBar().setUI(originalScrollBarUI); } - private static final Logger LOG = Logger.getLogger(ActionVariableMarker.class.getName()); + private static final Logger LOG = Logger.getLogger(VariableMarker.class.getName()); @Override public void propertyChange(PropertyChangeEvent evt) { @@ -373,30 +360,28 @@ public class ActionVariableMarker implements SyntaxComponent, CaretListener, Pro String fullText = sDoc.getText(0, sDoc.getLength()); - SWF swf = null; - if (pane instanceof DebuggableEditorPane) { - DebuggableEditorPane dpane = (DebuggableEditorPane) pane; - swf = dpane.getSwf(); + if (!(pane instanceof LineMarkedEditorPane)) { + return; } - if (swf == null) { + SimpleParser parser = ((LineMarkedEditorPane) pane).getParser(); + if (parser == null) { return; } Map> newDefinitionPosToReferences = new LinkedHashMap<>(); Map newReferenceToDefinition = new LinkedHashMap<>(); - ActionScript2VariableParser varParser = new ActionScript2VariableParser(swf); - List newErrors = new ArrayList<>(); - varParser.parse(fullText, newDefinitionPosToReferences, newReferenceToDefinition, newErrors); + List newErrors = new ArrayList<>(); + parser.parse(fullText, newDefinitionPosToReferences, newReferenceToDefinition, newErrors); definitionPosToReferences = newDefinitionPosToReferences; referenceToDefinition = newReferenceToDefinition; - for (ActionVariableParseException ex : newErrors) { + for (SimpleParseException ex : newErrors) { errors.put((int) ex.position, ex.getMessage()); } } catch (BadLocationException | IOException | InterruptedException ex) { definitionPosToReferences.clear(); referenceToDefinition.clear(); //ex.printStackTrace(); - } catch (ActionParseException ex) { + } catch (SimpleParseException ex) { definitionPosToReferences.clear(); referenceToDefinition.clear(); errors.put((int) ex.position, ex.getMessage());