⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smallbasic.txt

📁 Small Basic解释器的完整java代码
💻 TXT
📖 第 1 页 / 共 2 页
字号:
    double val = 0.0;
    String str;

    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 + -