📄 parser.java
字号:
if (fDef.paramNames.size()!=params.size()) { parseError("Expected " + fDef.paramNames.size() + " parameters, Found " + params.size()); } //Create a new parser instance to handle call Parser p; Hashtable locals=new Hashtable(); //Push the params into the local scope for (n=0;n<fDef.paramNames.size();n++) { locals.put(fDef.paramNames.elementAt(n), params.elementAt(n)); } //watch for recursive calls if (gVars==null) { p=new Parser(host,locals,vars,funcs); } else { p=new Parser(host,locals,gVars,funcs); } //cache the current execution point oldLine=code.getCurLine(); p.setCode(code); //let it rip val=p.parse(fDef.startLine+1,fDef.endLine-1); //reset execution point code.setCurLine(oldLine); } else {//calls into super class code...} try { val=host.callFunction(name,params); } catch (Exception e) { parseError(e.getMessage()); } } return val; } //Handle calls to a function private Object parseCallFunc(String name) throws FSException { Vector params=new Vector(4); //Set up the parameters do { getNextToken(); if (tok.ttype==',') { getNextToken(); } else if (tok.ttype==')') { break; } params.addElement(parseExpr()); } while (tok.ttype==','); return callFunction(name,params); } //handles function definitions private void parseFunctionDef() throws FSException { FuncEntry fDef=new FuncEntry(); Object val; String name,fName; fDef.startLine=code.getCurLine(); getNextToken(); //should be the function name if (tok.ttype!=LexAnn.TT_FUNC) { parseError("Expected function start identifier"); } fName=(String)tok.value; getNextToken(); //should be a '(' if (tok.ttype!='(') { parseError("Expected ("); } getNextToken(); //parse the header... while(tok.ttype!=')') { if (tok.ttype!=LexAnn.TT_DEFINT&&tok.ttype!=LexAnn.TT_DEFSTRING) { parseError("Expected type name"); } val=null; //keep the compiler happy.. if (tok.ttype==LexAnn.TT_DEFINT) { val=new Integer(0); } else if (tok.ttype==LexAnn.TT_DEFSTRING) { val=new String(""); } getNextToken(); if (tok.ttype!=LexAnn.TT_WORD) { parseError("Expected function parameter name identifier"); } name=(String)tok.value; fDef.paramNames.addElement(name); fDef.params.put(name,val); getNextToken(); if (tok.ttype==',') getNextToken(); } //now we just skip to the endfunction while ((tok.ttype!=LexAnn.TT_EDEFFUNC)&&(tok.ttype!=LexAnn.TT_EOF)) { getNextToken(); if (tok.ttype==LexAnn.TT_DEFFUNC) parseError("Nested functions are illegal"); } fDef.endLine=code.getCurLine(); getNextToken(); funcs.put(fName,fDef); } //Expression parser private Object parseExpr() throws FSException{ ETreeNode curNode=null; boolean end=false; boolean skipTok=false; Object val; boolean negate=false; //flag for unary minus boolean not=false;//flag for unary not. boolean prevOp=true;//flag - true if previous value was an operator while (!end){ switch (tok.ttype) { //the various possible 'values' case LexAnn.TT_INTEGER: case LexAnn.TT_DOUBLE: case LexAnn.TT_STRING: case LexAnn.TT_WORD: case LexAnn.TT_FUNC: case LexAnn.TT_ARRAY:{ if (!prevOp){ parseError("Expected Operator"); } else { val=null; ETreeNode node=new ETreeNode(); node.type=ETreeNode.E_VAL; switch (tok.ttype){ //numbers - just get them case LexAnn.TT_INTEGER:{ val=(Integer)tok.value; break; } //functions - evaluate them case LexAnn.TT_FUNC:{ String name=(String)tok.value; getNextToken(); val=parseCallFunc(name); break; } //arrays - evaluate them case LexAnn.TT_ARRAY:{ String name=(String)tok.value; getNextToken(); //should be a '[' getNextToken(); //should be the index Object index=parseExpr(); try { val=host.getVar(name,index); } catch (Exception e) { parseError(e.getMessage()); } break; } //variables - resolve them case LexAnn.TT_WORD:{ if (hasVar((String)tok.value)) { val=getVar((String)tok.value); } else { try { val=host.getVar((String)tok.value,null); } catch (Exception e) { parseError(e.getMessage()); } } break; } //strings - just get again case LexAnn.TT_STRING:{ val=(String)tok.value; break; } } //unary not if (not){ if (val instanceof Integer){ if (((Integer)val).intValue()!=0){ val=new Integer(0); } else { val=new Integer(1); } not=false; } else { parseError("Type mismatch for !"); } } //unary minus if (negate){ if (val instanceof Integer){ val=new Integer(-((Integer)val).intValue()); } else { parseError("Type mistmatch for unary -"); } } node.value=val; if (curNode!=null){ if (curNode.left==null){ curNode.left=node; node.parent=curNode; curNode=node; } else if (curNode.right==null){ curNode.right=node; node.parent=curNode; curNode=node; } } else { curNode=node; } prevOp=false; } break; } /*operators - have to be more carefull with these. We build an expression tree - inserting the nodes at the right points to get a reasonable approximation to correct operator precidence*/ case LexAnn.TT_LEQ: case LexAnn.TT_LNEQ: case LexAnn.TT_MULT: case LexAnn.TT_DIV: case LexAnn.TT_MOD: case LexAnn.TT_PLUS: case LexAnn.TT_MINUS: case LexAnn.TT_LGR: case LexAnn.TT_LGRE: case LexAnn.TT_LLSE: case LexAnn.TT_LLS: case LexAnn.TT_NOT: case LexAnn.TT_LAND: case LexAnn.TT_LOR: { if (prevOp){ if (tok.ttype==LexAnn.TT_MINUS){ negate=true; } else if (tok.ttype==LexAnn.TT_NOT){ not=true; } else { parseError("Expected expression"); } } else { ETreeNode node=new ETreeNode(); node.type=ETreeNode.E_OP; node.value=new Integer(tok.ttype); if (curNode.parent!=null){ int curPrio=getPrio(tok.ttype); int parPrio= getPrio(((Integer)curNode.parent.value).intValue()); if (curPrio<=parPrio){ //this nodes parent is the current nodes grandparent node.parent=curNode.parent.parent; //our nodes left leg is now linked into the current nodes //parent node.left=curNode.parent; //hook into grandparent if (curNode.parent.parent!=null){ curNode.parent.parent.right=node; } //the current nodes parent is now us (because of above) curNode.parent=node; //set the current node. curNode=node; } else { //current node's parent's right is now us. curNode.parent.right=node; //our nodes left is the current node. node.left=curNode; //our nodes parent is the current node's parent. node.parent=curNode.parent; //curent nodes parent is now us. curNode.parent=node; //set the current node. curNode=node; } } else { //our node's left is the current node node.left=curNode; //current node's parent is us now //we don't have to set our parent, as it is null. curNode.parent=node; //set current node curNode=node; } prevOp=true; } break; } case '(': //start of an bracketed expression, recursively call ourself //to get a value { getNextToken(); val=parseExpr(); ETreeNode node=new ETreeNode(); node.value=val; node.type=ETreeNode.E_VAL; if (curNode!=null){ if (curNode.left==null){ curNode.left=node; node.parent=curNode; curNode=node; } else if (curNode.right==null){ curNode.right=node; node.parent=curNode; curNode=node;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -