📄 parser.java
字号:
printETree(node.right); } } */ private void parseIf() throws IOException, FSException,RetException { Integer val; int depth; boolean then=false; getNextToken(); Object obj=parseExpr(); if (obj instanceof Integer) val=(Integer)obj; else { if (obj instanceof FSObject) obj=((FSObject)obj).getObject(); if (obj instanceof Boolean) val=((Boolean)obj).booleanValue() ? FS_TRUE : FS_FALSE; else if (obj instanceof Integer) { // test needed a second time 'cause it may have been an FSObject before val=(Integer)obj; } else { parseError("If condition needs to be Integer"); return; // just to make sure the compiler doesn't complain // as we know parseError throws an exception (stupid compiler) } } //handle the one line if-then construct if (tok.ttype==LexAnn.TT_THEN){ getNextToken(); //is this a single line then (or just a optional then) if (tok.ttype!=LexAnn.TT_EOL){ //single line if then construct - run separately //tok.pushBack(); if (val.intValue()!=0){ parseStmt(); } else { //consume to EOL while(tok.ttype!=LexAnn.TT_EOL){ getNextToken(); } } then=true; } } if (!then){ if (val.intValue()!=0) { getNextToken(); while((tok.ttype!=LexAnn.TT_EIF)&& (tok.ttype!=LexAnn.TT_ELSE) && (tok.ttype!=LexAnn.TT_EOF)&& (tok.ttype!=LexAnn.TT_ELSIF)) { //run the body of the if parseStmt(); getNextToken(); } if (tok.ttype==LexAnn.TT_ELSE || tok.ttype==LexAnn.TT_ELSIF) { //skip else clause - //have to do this taking into acount nesting depth=1; do { getNextToken(); if (tok.ttype==LexAnn.TT_IF) depth++; if (tok.ttype==LexAnn.TT_EOF) parseError("can't find endif"); if (tok.ttype==LexAnn.TT_EIF) depth--; //A then could indicate a one line //if - then construct, then we don't increment //depth if (tok.ttype==LexAnn.TT_THEN) { getNextToken(); if (tok.ttype!=LexAnn.TT_EOL){ depth--; } tok.pushBack(); } } while(depth>0); getNextToken(); } else { getNextToken(); } } else { //skip to else clause depth=1; do { getNextToken(); if (tok.ttype==LexAnn.TT_IF )depth++; if (tok.ttype==LexAnn.TT_EOF) parseError("can't find endif"); if ((tok.ttype==LexAnn.TT_EIF)) depth--; if ((tok.ttype==LexAnn.TT_ELSE || tok.ttype==LexAnn.TT_ELSIF )&& depth==1) depth--; //A then could indicate a one line //if - then construct, then we don't increment //depth if (tok.ttype==LexAnn.TT_THEN) { getNextToken(); if (tok.ttype!=LexAnn.TT_EOL){ depth--; } tok.pushBack(); } } while(depth>0); if (tok.ttype==LexAnn.TT_ELSE) { getNextToken(); getNextToken(); //run else clause while(tok.ttype!=LexAnn.TT_EIF) { parseStmt(); getNextToken(); } getNextToken(); } else if (tok.ttype==LexAnn.TT_ELSIF){ parseIf(); } else { getNextToken(); } } } } private void parseWhile() throws IOException, FSException,RetException { //parses the while statement Integer val; boolean looping = true; int startLine; //int endPos; int depth; startLine=code.getCurLine(); while ( looping ) { getNextToken(); // a 'while' you would imagine Object obj=parseExpr(); if (obj instanceof Integer) val=(Integer)obj; else { if (obj instanceof FSObject) obj=((FSObject)obj).getObject(); if (obj instanceof Boolean) val=((Boolean)obj).booleanValue() ? FS_TRUE : FS_FALSE; else if (obj instanceof Integer) { // test needed a second time 'cause it may have been an FSObject before val=(Integer)obj; } else { parseError("While condition needs to be Integer"); return; // just to make sure the compiler doesn't complain // as we know parseError throws an exception (stupid compiler) } } getNextToken(); if (val.intValue()==0) { looping = false; } else { while( (tok.ttype!=LexAnn.TT_EWHILE) && (tok.ttype!=LexAnn.TT_EOF) ) { parseStmt(); getNextToken(); } //reset to start of while loop.... code.setCurLine(startLine); resetTokens(); } } //skip to endwhile depth=1; do { getNextToken(); if (tok.ttype==LexAnn.TT_WHILE) depth++; if (tok.ttype==LexAnn.TT_EWHILE) depth--; if (tok.ttype==LexAnn.TT_EOF) parseError("can't find endwhile"); } while (depth>0); getNextToken(); } private void parseVarDef() throws IOException, FSException { String name; int type=tok.ttype; do { getNextToken(); if (tok.ttype!=LexAnn.TT_WORD) { parseError("Expected variable name identifier,"); } name=(String)tok.value; switch (type){ case LexAnn.TT_DEFINT: { addVar(name,FS_FALSE); break; } case LexAnn.TT_DEFSTRING:{ addVar(name,new String("")); break; } case LexAnn.TT_DEFDOUBLE:{ addVar(name,new Double(0)); break; } case LexAnn.TT_DEFOBJECT:{ addVar(name,new FSObject()); break; } } getNextToken(); if (tok.ttype==LexAnn.TT_EQ){ getNextToken(); setVar(name,parseExpr()); } else if (tok.ttype!=',' && tok.ttype!=LexAnn.TT_EOL) { parseError("Expected ','"); } } while (tok.ttype!=LexAnn.TT_EOL); } //format an error message and throw FSException private void parseError(String s) throws FSException { // set up our error block error=new String[6]; error[0]=s; error[1]=(new Integer(code.getCurLine())).toString(); error[2]=code.getLineAsString(); error[3]=tok.toString();; error[4]=vars.toString(); if (gVars!=null) error[5]=(gVars==null)?"":gVars.toString(); // build the display string s="\n\t"+s+"\n"+getContext(); throw new FSException(s); } /** * get the current context (executed line, variables etc) * @return */ public String getContext() { int l=code.getCurLine(); String s="\t\t at line:" + l + " "; if (l>-1) { s+="\n\t\t\t "+code.getLineAsString(l-2); s+="\n\t\t\t "+code.getLineAsString(l-1); s+="\n\t\t\t> "+code.getLineAsString(l)+" <"; s+="\n\t\t\t "+code.getLineAsString(l+1); s+="\n\t\t\t "+code.getLineAsString(l+2); s=s+ "\n\t\t current token:" + tok.toString();; s=s+ "\n\t\t Variable dump:" + vars; if (gVars!=null) { s=s+ "\n\t\t Globals:" + gVars; } } else s+="\n\t\t\t> "+tok.getLine()+" <"; return s; } //return the error block String[] getError() { return error; } // Other non SM related routines //misc token access routines private void getNextToken() throws IOException { if (tok.ttype==LexAnn.TT_EOL) { if (code.getCurLine() < maxLine) { code.setCurLine(code.getCurLine()+1); tok.setString(code.getLine()); tok.nextToken(); } else { tok.ttype=LexAnn.TT_EOF; //the only place this gets set } } else { tok.nextToken(); } } private void resetTokens() throws IOException { tok.setString(code.getLine()); tok.nextToken(); } //variable access routines void addVar(String name,Object value) throws FSException { if (vars.containsKey(name)) { parseError("Already defined in this scope: " + name ); } vars.put(name,value); } public Object getVar(String name) { if (subParser!=null) return subParser.getVar(name); if (vars.containsKey(name)) { return vars.get(name); } else { if (gVars!=null) { if (gVars.containsKey(name)) { return gVars.get(name); } } } // variable not found, try extensions try { return host.getVarEntry( name, null ); } catch ( Exception e ) {} return null; //shouldn't get here } // setVar allows assigning objects only when the objects are of the same type // OR you can assign a String, Integer or Double to an FSObject if the contained object already // has the same type. Note that you can change the type of the embedded object for "object" variables. public void setVar(String name,Object val) throws FSException { Object obj; if (val==null) parseError("set variable "+name+" with null value"); if (subParser!=null) { subParser.setVar(name,val); return; } if ( (obj=vars.get(name)) != null ) { if (val.getClass() != obj.getClass()) { //special case for FSObject allow asignment of either same //class or _any_ class if FSObject is already null //also allow assignment of null to any FSObject if (obj instanceof FSObject) { if (((FSObject)obj).getObject()==null){ val=new FSObject(val); } else if(((FSObject)obj).getObject().getClass()==val.getClass()){ val=new FSObject(val); } else { parseError("Incompatible types"); } } else{ parseError("Incompatible types"); } } vars.remove(name); vars.put(name,val); } else if ( (obj=gVars.get(name)) != null ) { if (val.getClass() != obj.getClass()) { parseError("Incompatible types"); } gVars.remove(name); gVars.put(name,val); } } public boolean hasVar(String name) { if (subParser!=null) return subParser.hasVar(name); if (gVars==null) { return vars.containsKey(name); } else { return vars.containsKey(name) || gVars.containsKey(name); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -