Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 401|回复: 0

[Java基础知识]一个简单的表达式解析器

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-1 04:51:53 | 显示全部楼层 |阅读模式
    一个简单的表达式解析器,这个解析器可以计算仅由数字、运算符和括号组成的表达式的值。
    下面是演示这个解析器的代码:
    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 = "";  
       
       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;   
       }   
          
    }  
      

      
      
       
       

         
       

         
       
      



    源码下载:http://file.javaxxz.com/2014/10/1/045153250.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-2 04:24 , Processed in 0.372026 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表