首页 | 注册 | 登陆
首页 >> 技术专栏 >> java文章 >> java基础 

一个简单的表达式解析器


作者java 来源java 加入时间:2006年02月21日
摘要:
一个简单的表达式解析器
   ,这个解析器可以计算仅由数字、运算符和括号组成的表达式的值。下面是演示这个解析器的代码:
import java.io.*; 
  …

转载:转载请保留本信息,本文来自
http://www.51dibs.com
/html/2006/article/info2/a_6ea71bbe6afaf436.htm




一个简单的表达式解析器


站点:爱心种子小博士 关键字:一个简单的表达式解析器




一个简单的表达式解析器
   一个简单的表达式解析器,这个解析器可以计算仅由数字、运算符和括号组成的表达式的值。下面是演示这个解析器的代码:
import java.io.*; 
  
class PDemo {  
  public static void main(String args[])  
    throws IOException 
  {  
    String expr; 
 
    BufferedReader br = new  BufferedReader(new InputStreamReader(System.in)); 
    Parser p = new Parser();  
  
    System.out.println("Enter an empty expression to stop.");  
  
    for(;;) {  
      System.out.print("Enter expression: ");  
      expr = br.readLine();  //从命令行输入表达式
      if(expr.equals("")) break;  
      try { 
        System.out.println("Result: " + p.evaluate(expr));  //计算表达式的值并输出
        System.out.println(); 
      } catch (ParserException exc) { 
        System.out.println(exc); 
      } 
    }  
  }  
}

运行结果:

C:\java>java    PDemo
Enter an empty expression to stop.
Enter expression: 3+7*9
Result: 66.0

Enter expression: (2+3)-7*9
Result: -58.0

Enter expression:

C:\java>
附解析器源码:
/*   
   不能处理变量的递归下降的表达式解析器  
 */  
   
// 处理错误的异常类
class ParserException extends Exception {  
  String errStr; // describes the error 
 
  public ParserException(String str) { 
    errStr = str; 
  }   
  
  public String toString() {  
    return errStr; 
  }  
}  
  
class Parser {  
  // 标识符的类型
  final int NONE = 0; 
  final int DELIMITER = 1; //分隔符:+、-、*、/、%、^、=、()
  final int VARIABLE = 2; //变量
  final int NUMBER = 3; //数字
 
  // 这些的语法错误的类型
  final int SYNTAX = 0; //表达式不正确
  final int UNBALPARENS = 1; //括号不对称
  final int NOEXP = 2; //没有表达式
  final int DIVBYZERO = 3; //被零除
 
  // 这个标识符表示表达式结束
  final String EOE = "\0"; 
 
  private String exp;   // 字符串表达式
  private int expIdx;   // 标识符当前索引
  private String token; // 标识符  
  private int tokType;  // 标识符的类型  
  
  // 计算表达式的值并返回结果.  
  public double evaluate(String expstr) throws ParserException 
  {  
    double result;  
    exp = expstr;  
    expIdx = 0;   
   
    getToken();  
    if(token.equals(EOE))  
      handleErr(NOEXP); // no expression present  
 
    // Parse and evaluate the expression. 
    result = evalExp2();  
  
    if(!token.equals(EOE)) // last token must be EOE  
      handleErr(SYNTAX);  
  
    return result;  
  }  
    
  // Add or subtract two terms.  
  private double evalExp2() throws ParserException 
  {  
    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 ParserException 
  {  
    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 ParserException 
  {  
    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 ParserException 
  {  
    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 ParserException 
  {  
    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.  
  private double atom() throws ParserException  
  {  
    double result = 0.0; 
 
    switch(tokType) {  
      case NUMBER:  
        try {  
          result = Double.parseDouble(token);  
        } catch (NumberFormatException exc) {  
          handleErr(SYNTAX);  
        }  
        getToken();  
        break; 
      default:  
        handleErr(SYNTAX);  
        break;  
    }  
    return result; 
  }  
    
  // Handle an error.  
  private void handleErr(int error) throws ParserException 
  {  
    String[] err = {  
      "Syntax Error",  
      "Unbalanced Parentheses",  
      "No Expression Present",  
      "Division by Zero"  
    };  
  
    throw new ParserException(err[error]);  
  }  
    
  // Obtain the next token.  
  private void getToken()  
  {  
    tokType = NONE;  
    token = "";  
     
    // Check for end of expression.  
    if(expIdx == exp.length()) { 
      token = EOE; 
      return; 
    } 
    
    // Skip over white space. 
    while(expIdx < exp.length() &&  
      Character.isWhitespace(exp.charAt(expIdx))) ++expIdx;  
  
    // Trailing whitespace ends expression. 
    if(expIdx == exp.length()) { 
      token = EOE; 
      return; 
    } 
  
    if(isDelim(exp.charAt(expIdx))) { // is operator  
      token += exp.charAt(expIdx);  
      expIdx++;  
      tokType = DELIMITER;  
    }  
    else if(Character.isLetter(exp.charAt(expIdx))) { // is variable  
      while(!isDelim(exp.charAt(expIdx))) {  
        token += exp.charAt(expIdx);  
        expIdx++;  
        if(expIdx >= exp.length()) break;  
      }  
      tokType = VARIABLE;  
    }  
    else if(Character.isDigit(exp.charAt(expIdx))) { // is number  
      while(!isDelim(exp.charAt(expIdx))) {  
        token += exp.charAt(expIdx);  
        expIdx++;  
        if(expIdx >= exp.length()) break;  
      }  
      tokType = NUMBER;  
    }  
    else { // unknown character terminates expression 
      token = EOE; 
      return; 
    } 
  }  
    
  // Return true if c is a delimiter.  
  private boolean isDelim(char c)  
  {  
    if((" +-/*%^=()".indexOf(c) != -1))  
      return true;  
    return false;  
  }  
    



发布人:love
→ 推荐给我的好友 → 报告错误链接
上篇文章:用Java实现的分形程序
下篇文章:辗转相除法求最大公约数
〖文章打印〗
〖关闭窗口〗
发表评论
查看评论
中“一个简单的表达式解析器”相关内容 中“一个简单的表达式解析器”相关内容
中“一个简单的表达式解析器”相关内容 中“一个简单的表达式解析器”相关内容
中“一个简单的表达式解析器”相关内容 中“一个简单的表达式解析器”相关内容

关于我们网站留言友情链接与我在线与我聊天领取红包管理TOP