//-------------------------------------------------------------------------------------------------- // // @ CopyRight Roberti & Parau Enterprises, Inc. 2021-2023 // // This work is licensed under the Creative Commons Attribution-NoDerivatives 4.0 International License. // To view a copy of this license, visit http://creativecommons.org/licenses/by-nd/4.0/ // or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. // //-------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------ // // Javacc parser for DVASM // //------------------------------------------------------------------------------ options { STATIC= false; SUPPORT_CLASS_VISIBILITY_PUBLIC= true; FORCE_LA_CHECK= true; LOOKAHEAD= 1; DEBUG_TOKEN_MANAGER= false; } PARSER_BEGIN(DVInputParser) package framework; import java.io.IOException; import java.util.LinkedList; import java.util.HashMap; import javax.script.ScriptException; public class DVInputParser { // // Class fields // private DVStatements statements; private DVMacroJSApi jSApi; private DVMacros macros; private DVStatements.Statement currStatement; private Token currLabel= null; private DVOpCodeParm opCodeParm= null; private Token currKey= null; private boolean subParmState= false; private boolean subParmEnd= false; private DVExpression currExpression= null; private DVMacros.Macro currMacro= null; private int macroPosParmNo; private int macroParmListNo; private String macroEvalParm; LinkedList macroNestStack= new LinkedList(); HashMap macroKeyParm; // // Get current state in string form // protected String getState() { return DVInputParserTokenManager.lexStateNames[token_source.curLexState]; } } PARSER_END(DVInputParser) // // Token manager declarations // TOKEN_MGR_DECLS : { protected DVStatements statements= null; protected DVMacros macros; protected DVMacroJSApi jSApi= null; protected int lexNest; protected DVMacros.Macro currMacro= null; protected int macroNestCount; private String getState() { return lexStateNames[curLexState]; } void switchFromUnaryState() { switch(curLexState) { case PARM_EXPR_START_STATE : case PARM_EXPR_UNARY_STATE : SwitchTo(PARM_EXPR_VALUE_STATE); return; case PARM_EXPR_UNARY_NEST_STATE : SwitchTo(PARM_EXPR_VALUE_NEST_STATE); return; case KEYP_EXPR_START_STATE : case KEYP_EXPR_UNARY_STATE : SwitchTo(KEYP_EXPR_VALUE_STATE); return; case KEYP_EXPR_UNARY_NEST_STATE : SwitchTo(KEYP_EXPR_VALUE_NEST_STATE); return; case SUBP_EXPR_UNARY_STATE : SwitchTo(SUBP_EXPR_VALUE_STATE); return; case SUBP_EXPR_UNARY_NEST_STATE : SwitchTo(SUBP_EXPR_VALUE_NEST_STATE); return; default : return; } } void switchFromValueState() { switch(curLexState) { case PARM_EXPR_START_STATE : case PARM_EXPR_UNARY_STATE : case PARM_EXPR_VALUE_STATE : SwitchTo(PARM_EXPR_BINARY_STATE); return; case PARM_EXPR_UNARY_NEST_STATE : case PARM_EXPR_VALUE_NEST_STATE : SwitchTo(PARM_EXPR_BINARY_NEST_STATE); return; case KEYP_EXPR_START_STATE : case KEYP_EXPR_UNARY_STATE : case KEYP_EXPR_VALUE_STATE : SwitchTo(KEYP_EXPR_BINARY_STATE); return; case KEYP_EXPR_UNARY_NEST_STATE : case KEYP_EXPR_VALUE_NEST_STATE : SwitchTo(KEYP_EXPR_BINARY_NEST_STATE); return; case SUBP_EXPR_UNARY_STATE : case SUBP_EXPR_VALUE_STATE : SwitchTo(SUBP_EXPR_BINARY_STATE); return; case SUBP_EXPR_UNARY_NEST_STATE : case SUBP_EXPR_VALUE_NEST_STATE : SwitchTo(SUBP_EXPR_BINARY_NEST_STATE); return; default : return; } } void switchFromBinaryState() { switch(curLexState) { case PARM_EXPR_BINARY_STATE : SwitchTo(PARM_EXPR_VALUE_STATE); return; case PARM_EXPR_BINARY_NEST_STATE : SwitchTo(PARM_EXPR_VALUE_NEST_STATE); return; case SUBP_EXPR_BINARY_STATE : SwitchTo(SUBP_EXPR_VALUE_STATE); return; case SUBP_EXPR_BINARY_NEST_STATE : SwitchTo(SUBP_EXPR_VALUE_NEST_STATE); return; case KEYP_EXPR_BINARY_STATE : SwitchTo(KEYP_EXPR_VALUE_STATE); return; case KEYP_EXPR_BINARY_NEST_STATE : SwitchTo(KEYP_EXPR_VALUE_NEST_STATE); return; default : return; } } void switchToNestedState() { switch(curLexState) { case PARM_EXPR_START_STATE : case PARM_EXPR_UNARY_STATE : case PARM_EXPR_VALUE_STATE : SwitchTo(PARM_EXPR_UNARY_NEST_STATE); return; case KEYP_EXPR_START_STATE : case KEYP_EXPR_UNARY_STATE : case KEYP_EXPR_VALUE_STATE : SwitchTo(KEYP_EXPR_UNARY_NEST_STATE); return; case SUBP_EXPR_UNARY_STATE : case SUBP_EXPR_VALUE_STATE : SwitchTo(SUBP_EXPR_UNARY_NEST_STATE); return; default : return; } } void switchFromNestedState() { switch(curLexState) { case PARM_EXPR_BINARY_NEST_STATE : SwitchTo(PARM_EXPR_BINARY_STATE); return; case KEYP_EXPR_BINARY_NEST_STATE : SwitchTo(KEYP_EXPR_BINARY_STATE); return; case SUBP_EXPR_BINARY_NEST_STATE : SwitchTo(SUBP_EXPR_BINARY_STATE); return; default : return; } } void switchAferComma() { switch(curLexState) { case PARM_EXPR_START_STATE : case PARM_EXPR_END_STATE : case PARM_EXPR_UNARY_STATE : case PARM_EXPR_BINARY_STATE : case KEYP_EXPR_START_STATE : case KEYP_EXPR_UNARY_STATE : case KEYP_EXPR_BINARY_STATE : SwitchTo(PARM_EXPR_START_STATE); return; case SUBP_EXPR_UNARY_STATE : case SUBP_EXPR_BINARY_STATE : SwitchTo(SUBP_EXPR_UNARY_STATE); return; default : return; } } } // // List of all states used // // MACRO_STATE // OPCODE_PARM_STATE // SUBP_EXPR_BINARY_NEST_STATE // SUBP_EXPR_VALUE_NEST_STATE // SUBP_EXPR_UNARY_NEST_STATE // SUBP_EXPR_BINARY_STATE // SUBP_EXPR_VALUE_STATE // SUBP_EXPR_UNARY_STATE // SUBP_EXPR_START_STATE // KEYP_EXPR_BINARY_NEST_STATE // KEYP_EXPR_VALUE_NEST_STATE // KEYP_EXPR_UNARY_NEST_STATE // KEYP_EXPR_BINARY_STATE // KEYP_EXPR_VALUE_STATE // KEYP_EXPR_UNARY_STATE // KEYP_EXPR_START_STATE // PARM_EXPR_BINARY_NEST_STATE // PARM_EXPR_VALUE_NEST_STATE // PARM_EXPR_UNARY_NEST_STATE // PARM_EXPR_BINARY_STATE // PARM_EXPR_VALUE_STATE // PARM_EXPR_UNARY_STATE // PARM_EXPR_END_STATE // PARM_EXPR_START_STATE // OPCODE_STATE // DEFAULT // // Start of statement token // TOKEN : { ( | )*)".")* ( ( | )*))> : OPCODE_STATE } TOKEN : { : OPCODE_STATE } // // Identifiers // TOKEN: { ( | )*)".")* ( ( | )*))> { if ((currMacro= macros.get(jSApi, image.toString())) != null) SwitchTo(MACRO_STATE); else SwitchTo(OPCODE_PARM_STATE); lexNest= 0; } } // // Switch to expression after blank for opCode parms // TOKEN: { : PARM_EXPR_START_STATE } // // Expression operators - UNARY state // TOKEN: { | | { switchFromUnaryState(); } | { switchFromUnaryState(); } } // // Expression operators - VALUE state - not NESTED // TOKEN: { (":") )> : PARM_EXPR_BINARY_STATE } // // Expression operators - VALUE and UNARY state // TOKEN: { ( | )*)".")* ( ( | )*)) ((("@") (< LETTER > (< LETTER > | < DIGIT >)*)) ((".@") (< LETTER > (< LETTER > | < DIGIT >)*))*))+> { switchFromValueState(); } | ( | )*)".")* ( ( | )*))> { switchFromValueState(); } | (".$") (["l","L"]["e","E"]["n","N"]["g","G"]["t","T"]["h","H"]))> { switchFromValueState(); } | (".$") (["r","R"]["e","E"]["p","P"]["l","L"]))> { switchFromValueState(); } | (".$") (["s","S"]["i","I"]["z","Z"]["e","E"]))> { switchFromValueState(); } | { switchFromValueState(); } | )+ ["."] ()*) (["E","e"] (["+","-"])? ()+)?) | ((()* ["."] ()+) (["E","e"] (["+","-"])? ()+)?) | ( ()+ ["E","e"] (["+","-"])? ()+))> { switchFromValueState(); } | )+)> { switchFromValueState(); } | )+) ((("_") ()+)*))> { switchFromValueState(); } | )+) ((("_") ()+)*))> { switchFromValueState(); } | ("'")> { switchFromValueState(); } | )* ["\""])> { switchFromValueState(); } | { switchToNestedState(); lexNest++; } | <#LETTER: ["a"-"z","A"-"Z","_"]> | <#BINDIGIT: ["0"-"1"]> | <#DIGIT: ["0"-"9"]> | <#HEXDIGIT: ["0"-"9","A"-"F","a"-"f"]> | <#SINGLECHARDQ: ([" "-"!","#"-"~"]) | ("\\0") | ("\\b") | ("\\t") | ("\\n") | ("\\v") | ("\\f") | ("\\r") | (("\\x") ) | ("\\\"") | ("\\\'") | ("\\\\")> | <#SINGLECHARSQ: ([" "-"&","("-"~"]) | ("\\0") | ("\\b") | ("\\t") | ("\\n") | ("\\v") | ("\\f") | ("\\r") | (("\\x") ) | ("\\\"") | ("\\\'") | ("\\\\")> } // // Keyword tokens - PARM START state // TOKEN: { ( | )*) ("="))> : KEYP_EXPR_START_STATE } // // Expression operators - BINARY state // TOKEN: { { switchFromBinaryState(); } | { switchFromBinaryState(); } | { switchFromBinaryState(); } | { switchFromBinaryState(); } | { switchFromBinaryState(); } | { switchFromBinaryState(); } | { switchFromBinaryState(); } | >")> { switchFromBinaryState(); } | ")> { switchFromBinaryState(); } | { switchFromBinaryState(); } | =")> { switchFromBinaryState(); } | { switchFromBinaryState(); } | { switchFromBinaryState(); } | { switchFromBinaryState(); } | { switchFromBinaryState(); } | { switchFromBinaryState(); } } // // Expression operators - BINARY state - not NESTED // TOKEN: { : SUBP_EXPR_UNARY_STATE } // // Expression operators - BINARY state - not NESTED // TOKEN: { : PARM_EXPR_END_STATE } // // Expression operators - BINARY state - not NESTED // TOKEN: { { switchAferComma(); } } // // Expression operators - BINARY state - NESTED only // TOKEN: { { lexNest--; if (lexNest <= 0) switchFromNestedState(); } } // // Macro tokens // TOKEN [IGNORE_CASE]: { } TOKEN: { | | | | { this.macroNestCount++; } | { this.macroNestCount--; } | { this.macroNestCount++; } | { this.macroNestCount--; } | { this.macroNestCount++; } | { this.macroNestCount--; } | | | } // // Blanks skip // // MACRO_STATE , Need to capture blanks // OPCODE_PARM_STATE, After OpCode need to verify blanks before parms // DEFAULT, Before OpCode to check if label is there SKIP : { < ((" ") | ("\t"))> } <*> SKIP : { < ("\n") > } // // Invalid characters to avoid Token Manager error // <*> TOKEN : { < INVALID_CHAR: (~[]) > } // // Start grammar here // void start(DVStatements statements): { this.statements= statements; this.currStatement= statements.currStatement; this.jSApi= statements.jSApi; this.macros= jSApi.macros; this.token_source.statements= statements; this.token_source.jSApi= jSApi; this.token_source.macros= jSApi.macros; Token t; String macroCode; } { ( ( t=