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

📄 sbasic.java

📁 此为"The Art of JAVA"书籍关于设计解析器之码。很旧的一本书了
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    int var; 
    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 + -