zoukankan      html  css  js  c++  java
  • 递归向下解析算术表达式(三)

    本例代码下载:https://files.cnblogs.com/files/heyang78/MathAnalyzer2-20200524-1.zip

    较原有版本,是多了Node类和TreeBuilder类,二者用于构建表达式树:

    Node类:

    package com.heyang;
    
    public class Node {
        private String text;
        private Node leftChild;
        private Node rightChild;
        
        public Node() {
            this("");
        }
        
        public Node(String text) {
            this.text=text;
        }
        
        public String getText() {
            return text;
        }
        public void setText(String text) {
            this.text = text;
        }
        public Node getLeftChild() {
            return leftChild;
        }
        public void setLeftChild(Node leftChild) {
            this.leftChild = leftChild;
        }
        public Node getRightChild() {
            return rightChild;
        }
        public void setRightChild(Node rightChild) {
            this.rightChild = rightChild;
        }
    }

    TreeBuilder类:

    package com.heyang;
    
    import java.util.List;
    
    public class TreeBuilder {
        private List<Token> tokens;
        private int tokenIdx;
        private Node root;
        
        public TreeBuilder(List<Token> tokens)  throws AnalyzerExp{
            this.tokens=tokens;
            this.tokenIdx=0;
            
            root=parse_expression();
        }
        
        public Node getRoot() {
            return root;
        }
        
        private Token fetchToken() {
            if(tokenIdx>=tokens.size()) {
                return null;
            }else {
                Token t=tokens.get(tokenIdx);
                tokenIdx++;
                return t;
            }        
        }
        
        private void returnToken() {
            if(tokenIdx>0) {
                tokenIdx--;
            }
        }
        
        private Node parse_expression() throws AnalyzerExp{
            Node left,right;
            Token currentToken;
            
            left=parse_term();
            for(;;) {
                currentToken=fetchToken();
                if(currentToken==null) {
                    return left;
                }
                
                if(currentToken.getType()!=Token.TYPE_PLUS && currentToken.getType()!=Token.TYPE_MINUS) {
                    returnToken();
                    break;
                }
                
                right=parse_term();
                
                Node plusMinusNode=new Node(currentToken.getText());
                plusMinusNode.setLeftChild(left);
                plusMinusNode.setRightChild(right);
                left=plusMinusNode;
            }
            
            return left;
        }
        
        private Node parse_term() throws AnalyzerExp{
            Node left,right;
            Token currentToken;
            
            left=parse_primary_exp();
            for(;;) {
                currentToken=fetchToken();
                if(currentToken==null) {
                    return left;
                }
                
                if(currentToken.getType()!=Token.TYPE_MULTI && currentToken.getType()!=Token.TYPE_DIVIDE) {
                    returnToken();
                    break;
                }
                
                right=parse_primary_exp();
                
                Node multiDivideNode=new Node(currentToken.getText());
                multiDivideNode.setLeftChild(left);
                multiDivideNode.setRightChild(right);
                left= multiDivideNode;
            }
            
            return left;
        }
        
        private Node parse_primary_exp() throws AnalyzerExp{
            Token currToken;
            
            currToken=fetchToken();
            if(currToken==null) {
                return null;
            }
            
            if(currToken.getType()==Token.TYPE_DIGITAL) {
                return new Node(currToken.getText());
            }else if(currToken.getType()==Token.TYPE_LEFT_PAREN){
                Node retval=parse_expression();
                
                currToken=fetchToken();
                if(currToken==null) {
                    return retval;
                }
                
                if(currToken.getType()!=Token.TYPE_RIGHT_PAREN) {
                    throw new AnalyzerExp("missing )");
                }
                
                return retval;
            }else {
                throw new AnalyzerExp(currToken+" should be a digital.");
            }
        }
    }

    解析效果:

    1+2+3=6.0
          +      
        /       
      +       3  
     /          
    1   2        
    1+2+3+4=10.0
                +            
             /              
          +           4      
        /                   
      +       3              
     /                      
    1   2                    
    1+2+3+4+5=15.0
                            +                        
                        /                           
                    +               5                
                 /                                  
              +           4                          
            /                                       
          +       3                                  
         /                                          
        1   2                                        
    1+(2+3)*4=21.0
                +            
             /              
          1           *      
                    /       
                  +       4  
                 /          
                2   3        
    1+(2+3)*4+5=26.0
                            +                        
                        /                           
                    +               5                
                 /                                  
              1           *                          
                        /                           
                      +       4                      
                     /                              
                    2   3                            

    --2020年5月24日--

  • 相关阅读:
    程序员累了怎么办?
    vue.js 组件注册实例
    background新增的N个强悍功能!!!
    相思别去问得失
    你说的我正在经历
    千折扇
    盼盼Degenerate——清除浮动的方法
    let 和 var定义变量的区别-盼盼Degenerate
    winform关闭窗体时,给用户友好提示!
    web学习笔记1--HTML
  • 原文地址:https://www.cnblogs.com/heyang78/p/12950357.html
Copyright © 2011-2022 走看看