📄 sbasic.java
字号:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); getToken(); // see if prompt string is present if(tokType == QUOTEDSTR) { // if so, print it and check for comma System.out.print(token); getToken(); if(!token.equals(",")) handleErr(SYNTAX); getToken(); } else System.out.print("? "); // otherwise, prompt with ? // get the input var var = Character.toUpperCase(token.charAt(0)) - 'A'; try { str = br.readLine(); val = Double.parseDouble(str); // read the value } catch (IOException exc) { handleErr(INPUTIOERROR); } catch (NumberFormatException exc) { /* You might want to handle this error differently than the other interpreter errors. */ System.out.println("Invalid input."); } vars[var] = val; // store it } // Execute a GOSUB. private void gosub() throws InterpreterException { Integer loc; getToken(); // Find the label to call. loc = (Integer) labelTable.get(token); if(loc == null) handleErr(UNDEFLABEL); // label not defined else { // Save place to return to. gStack.push(new Integer(progIdx)); // Start program running at that loc. progIdx = loc.intValue(); } } // Return from GOSUB. private void greturn() throws InterpreterException { Integer t; try { // Restore program index. t = (Integer) gStack.pop(); progIdx = t.intValue(); } catch(EmptyStackException exc) { handleErr(RETURNWITHOUTGOSUB); } } // **************** Expression Parser **************** // Parser entry point. private double evaluate() throws InterpreterException { double result = 0.0; getToken(); if(token.equals(EOP)) handleErr(NOEXP); // no expression present // Parse and evaluate the expression. result = evalExp1(); putBack(); return result; } // Process relational operators. private double evalExp1() throws InterpreterException { double l_temp, r_temp, result; char op; result = evalExp2(); // If at end of program, return. if(token.equals(EOP)) return result; op = token.charAt(0); if(isRelop(op)) { l_temp = result; getToken(); r_temp = evalExp1(); switch(op) { // perform the relational operation case '<': if(l_temp < r_temp) result = 1.0; else result = 0.0; break; case LE: if(l_temp <= r_temp) result = 1.0; else result = 0.0; break; case '>': if(l_temp > r_temp) result = 1.0; else result = 0.0; break; case GE: if(l_temp >= r_temp) result = 1.0; else result = 0.0; break; case '=': if(l_temp == r_temp) result = 1.0; else result = 0.0; break; case NE: if(l_temp != r_temp) result = 1.0; else result = 0.0; break; } } return result; } // Add or subtract two terms. private double evalExp2() throws InterpreterException { char op; double result; double partialResult; result = evalExp3(); while((op = token.charAt(0)) == '+' || op == '-') { getToken(); partialResult = evalExp3(); switch(op) { case '-': result = result - partialResult; break; case '+': result = result + partialResult; break; } } return result; } // Multiply or divide two factors. private double evalExp3() throws InterpreterException { char op; double result; double partialResult; result = evalExp4(); while((op = token.charAt(0)) == '*' || op == '/' || op == '%') { getToken(); partialResult = evalExp4(); switch(op) { case '*': result = result * partialResult; break; case '/': if(partialResult == 0.0) handleErr(DIVBYZERO); result = result / partialResult; break; case '%': if(partialResult == 0.0) handleErr(DIVBYZERO); result = result % partialResult; break; } } return result; } // Process an exponent. private double evalExp4() throws InterpreterException { double result; double partialResult; double ex; int t; result = evalExp5(); if(token.equals("^")) { getToken(); partialResult = evalExp4(); ex = result; if(partialResult == 0.0) { result = 1.0; } else for(t=(int)partialResult-1; t > 0; t--) result = result * ex; } return result; } // Evaluate a unary + or -. private double evalExp5() throws InterpreterException { double result; String op; op = ""; if((tokType == DELIMITER) && token.equals("+") || token.equals("-")) { op = token; getToken(); } result = evalExp6(); if(op.equals("-")) result = -result; return result; } // Process a parenthesized expression. private double evalExp6() throws InterpreterException { double result; if(token.equals("(")) { getToken(); result = evalExp2(); if(!token.equals(")")) handleErr(UNBALPARENS); getToken(); } else result = atom(); return result; } // Get the value of a number or variable. private double atom() throws InterpreterException { double result = 0.0; switch(tokType) { case NUMBER: try { result = Double.parseDouble(token); } catch (NumberFormatException exc) { handleErr(SYNTAX); } getToken(); break; case VARIABLE: result = findVar(token); getToken(); break; default: handleErr(SYNTAX); break; } return result; } // Return the value of a variable. private double findVar(String vname) throws InterpreterException { if(!Character.isLetter(vname.charAt(0))){ handleErr(SYNTAX); return 0.0; } return vars[Character.toUpperCase(vname.charAt(0))-'A']; } // Return a token to the input stream. private void putBack() { if(token == EOP) return; for(int i=0; i < token.length(); i++) progIdx--; } // Handle an error. private void handleErr(int error) throws InterpreterException { String[] err = { "Syntax Error", "Unbalanced Parentheses", "No Expression Present", "Division by Zero", "Equal sign expected", "Not a variable", "Label table full", "Duplicate label", "Undefined label", "THEN expected", "TO expected", "NEXT without FOR", "RETURN without GOSUB", "Closing quotes needed", "File not found", "I/O error while loading file", "I/O error on INPUT statement" }; throw new InterpreterException(err[error]); } // Obtain the next token. private void getToken() throws InterpreterException { char ch; tokType = NONE; token = ""; kwToken = UNKNCOM; // Check for end of program. if(progIdx == prog.length) { token = EOP; return; } // Skip over white space. while(progIdx < prog.length && isSpaceOrTab(prog[progIdx])) progIdx++; // Trailing whitespace ends program. if(progIdx == prog.length) { token = EOP; tokType = DELIMITER; return; } if(prog[progIdx] == '\r') { // handle crlf progIdx += 2; kwToken = EOL; token = "\r\n"; return; } // Check for relational operator. ch = prog[progIdx]; if(ch == '<' || ch == '>') { if(progIdx+1 == prog.length) handleErr(SYNTAX); switch(ch) { case '<': if(prog[progIdx+1] == '>') { progIdx += 2;; token = String.valueOf(NE); } else if(prog[progIdx+1] == '=') { progIdx += 2; token = String.valueOf(LE); } else { progIdx++; token = "<"; } break; case '>': if(prog[progIdx+1] == '=') { progIdx += 2;; token = String.valueOf(GE); } else { progIdx++; token = ">"; } break; } tokType = DELIMITER; return; } if(isDelim(prog[progIdx])) { // Is an operator. token += prog[progIdx]; progIdx++; tokType = DELIMITER; } else if(Character.isLetter(prog[progIdx])) { // Is a variable or keyword. while(!isDelim(prog[progIdx])) { token += prog[progIdx]; progIdx++; if(progIdx >= prog.length) break; } kwToken = lookUp(token); if(kwToken==UNKNCOM) tokType = VARIABLE; else tokType = COMMAND; } else if(Character.isDigit(prog[progIdx])) { // Is a number. while(!isDelim(prog[progIdx])) { token += prog[progIdx]; progIdx++; if(progIdx >= prog.length) break; } tokType = NUMBER; } else if(prog[progIdx] == '"') { // Is a quoted string. progIdx++; ch = prog[progIdx]; while(ch !='"' && ch != '\r') { token += ch; progIdx++; ch = prog[progIdx]; } if(ch == '\r') handleErr(MISSINGQUOTE); progIdx++; tokType = QUOTEDSTR; } else { // unknown character terminates program token = EOP; return; } } // Return true if c is a delimiter. private boolean isDelim(char c) { if((" \r,;<>+-/*%^=()".indexOf(c) != -1)) return true; return false; } // Return true if c is a space or a tab. boolean isSpaceOrTab(char c) { if(c == ' ' || c =='\t') return true; return false; } // Return true if c is a relational operator. boolean isRelop(char c) { if(relops.indexOf(c) != -1) return true; return false; } /* Look up a token's internal representation in the token table. */ private int lookUp(String s) { int i; // Convert to lowercase. s = s.toLowerCase(); // See if token is in table. for(i=0; i < kwTable.length; i++) if(kwTable[i].keyword.equals(s)) return kwTable[i].keywordTok; return UNKNCOM; // unknown keyword }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -