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

📄 parser.java

📁 JAVA 数学程序库 提供常规的数值计算程序包
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        {
            // something like:  a(:)
            ErrorLogger.debugLine("Parser: colon: (:)");
            operandStack.push(leftSide); // push left side back on stack
            return new Expression((OperatorToken)nextToken);
        }
        else
        {
            // e.g. 1:8
            if (rightSide instanceof Expression)
            {
                 Expression rightExpr = (Expression)rightSide;
                if (rightExpr.getData() instanceof ColonOperatorToken)
                {
                    // e.g. 2:<4:5>
                    ErrorLogger.debugLine("Parser: colon: "+leftSide.toString()+":"
                                                           +rightExpr.getChild(0).toString()+":"
                                                           +rightExpr.getChild(1).toString()      );
                    OperandToken[] opToken = { leftSide,
                                               rightExpr.getChild(0),
                                               rightExpr.getChild(1) };
                    return new Expression((OperatorToken)nextToken, opToken, 3);

                }
                else
                {
                    // e.g. 2:<6+7> (just one colon, but expression)
                    ErrorLogger.debugLine("Parser: colon: "+leftSide.toString()+":"+rightSide.toString());
                    return new Expression((OperatorToken)nextToken,
                                          leftSide,
                                          rightSide);
                }
            }
            else
            {
                // e.g.: 2:6
                ErrorLogger.debugLine("Parser: colon: "+leftSide.toString()+":"+rightSide.toString());
                return new Expression((OperatorToken)nextToken, leftSide, rightSide);
             }
            
        }
        
    } // end parseColonOperator


    /***********************************************************************************/
    /** parse <operand><operator><operand> (e.g. 3+4, 3*4, 3/4, 1+2*3+4*5)             */
    /* @param                                                                            */
    /* @param                                                                           */
    /* @return                                                                         */
    private OperandToken parseBinaryOperator(Token nextToken, Stack operandStack)
    {
        // operator for this operation 
        OperatorToken operator = (OperatorToken)nextToken;
        
        //get left parameter from operandStack 
        //(exception: if parsing "-a" left operand will be null)                    
        OperandToken leftSide = null;
        if (!operandStack.isEmpty())
            leftSide = (OperandToken)operandStack.pop(); 

        //parse right parameter                    
        OperandToken rightSide = parseSingle(operandStack, SINGLE);         

        // create new expression 
        Expression tree = new Expression(operator, leftSide, rightSide);
           
        // Check if priority is correct. e.g.: 2*3+4 => (2*3)+4
        // (left side and right side might be changed 
        //   if the operators (+-*^!') have different priorities)
        if (!(leftSide instanceof Expression))
            return tree;
        
        Expression    leftExpr   = (Expression)leftSide;
        OperatorToken leftBinary = (OperatorToken)leftExpr.getData();
        
        if (leftBinary == null)
            return tree;
            
        if (!(leftBinary instanceof BinaryOperatorToken))
            return tree;
            
        /* only priority swapping for binary operators + - * / ^ < > ... */
        // 1+2*3+4*5 should be parsed into ((1+(2*3))+(4*5))
        // 1/2-1+9   should be parsed into (((1 / 2) - 1) + 9)
        ErrorLogger.debugLine("priority ("+ leftBinary.getPriority()   +
                              ","         + operator.getPriority() +
                              ") <"       + leftSide.toString()  +
                              "> "        + operator.toString() +
                              " <"        + rightSide.toString() + ">");

        if (leftBinary.getPriority() < operator.getPriority())
        {
            // something like 2+3*4 : <2+3> * <4>    
            // change to              <2>   + <3*4>
            // left:       +
            //         <2>    <3>     
            ErrorLogger.debugLine("swapping priorities");
            OperandToken newLeft = leftExpr.getRight();
                        
            //already parsed right side is first operand of new right
            //operandStack.push(rightSide);
            
            //parse right
            
            //OperandToken newRight = (OperandToken)operandStack.pop();
            OperandToken newRight = new Expression((OperatorToken)operator,
                                                 leftExpr.getRight(),
                                                 rightSide); 
            
            // Check next token if it is a binary operator and call a parse() method 
            // until priority of next operator is lower/equals as the calling operator
            // (e.g. 1+2 * 3 <+> .... priority of <+> is lower than "*")
        	if (peekNextToken() instanceof BinaryOperatorToken)
            {
                
                BinaryOperatorToken nextBinary = (BinaryOperatorToken)peekNextToken();
                
                if (operator.getPriority() <= nextBinary.getPriority())
                {
                
                    // the current arithmetic expression is not terminated yet
                    // parse next operands
                    ErrorLogger.debugLine("Parser: BinaryOperator: recursive parsing");
                    operandStack.push(newRight);
                    
                    newRight = parseSingle(operandStack, SINGLE);
                }
            }
                    
            // create tree  again 
            tree  = new Expression((OperatorToken)leftBinary,
                                    leftExpr.getLeft(),
                                    newRight);
        }
        
        return tree;               
    } // end parseBinaryOperator


    /***********************************************************************************/
    /** parse <operand><operator> (e.g. 3! or !(a<3))                                           */
    /* @param                                                                            */
    /* @param                                                                           */
    /* @return                                                                         */
    private OperandToken parseUnaryOperator(Token nextToken, Stack operandStack)
    {

    	// if parsing !(a<3) or !3 operand stack is empty
    	if (operandStack.isEmpty())
    	{
    		ErrorLogger.debugLine("Parser: Unary !3 or ~3");
    		
    		UnaryOperatorToken tok = (UnaryOperatorToken)nextToken;
    		if (! ((tok.getValue()=='!') || (tok.getValue()=='~')))
    			Errors.throwParserException(" Unary operator by empty stack");
    		
			OperandToken operand = parseArithExpression(SINGLE);
			FunctionToken func = new FunctionToken("not");
			func.setOperand(operand);
    		return func;	
    	}
    	
    	// e.g. 3! 
        //get left parameter from operandStack                    
        OperandToken leftSide = (OperandToken)operandStack.pop(); 
    
        Expression tree = null;
        
        if ((leftSide instanceof DoubleNumberToken)   ||
            (leftSide instanceof MatrixToken)   ||
            (leftSide instanceof VariableToken) ||
            (leftSide instanceof FunctionToken)    )
        {
            // (e.g. 3! a! a++ a--)
            tree = new Expression((UnaryOperatorToken)nextToken, leftSide);
        }
        else if (leftSide instanceof Expression)
        {
            Expression leftExpr = (Expression)leftSide;
            
            Expression newRightOperand = new Expression((UnaryOperatorToken)nextToken, 
                                                        leftExpr.getRight());
            tree = new Expression(leftExpr.getData(),
                                  leftExpr.getLeft(),
                                  newRightOperand);
                                             
        }
        else
            Errors.throwParserException(" Unary operator");
                    
        return tree;
    } // end parseBinaryOperator


    /***********************************************************************************/
    /** parse expressions of the form value.function()                                 */
    /* @param  operand stack                                                            */
    /* @param  type of delimiters (including whitespaces or not)                         */
    /* @return parsed expression or variable token                                     */
    private OperandToken parseDotOperator(Stack operandStack, int deliTyp)
    {
        ErrorLogger.debugLine("Parser: DotOperator");
        
        // result of parsing dot operator
        OperandToken result;
        
        // the left operand has been parsed already
        OperandToken leftSide  = (OperandToken)operandStack.pop();
        
        // right side
        OperandToken rightSide = null; //parseSingle(operandStack, SINGLE);

        // check type of right side operand (e.g. a.bbbb or a.someFunction() )
        if (peekNextToken(deliTyp) instanceof VariableToken)
        {
            // (e.g. a.B or bar.foo)
            rightSide = (VariableToken)getNextToken(deliTyp);
        }
        else if (peekNextToken(deliTyp) instanceof FunctionToken)
        {
            // (e.g. a.sin() or a.getColor() )
            rightSide =  parseFunctionAndParameters((FunctionToken)getNextToken(deliTyp), null);
        }        
        else
            Errors.throwParserException("DotOperator: unknown right side");
            
        // create extended variable token or expression of dot-operator
        if ((leftSide  instanceof VariableToken) &&
            (rightSide instanceof VariableToken)   )
        {
            // (e.g.  a.length or system.A or a.bbb)
            String left  = ((VariableToken)leftSide).getName();
            String right = ((VariableToken)rightSide).getName();
            ErrorLogger.debugLine("Parser: " + left + "." + right);
            result = new VariableToken(left, right);
        }
        else
        {
            // (e.g. a.sin() or a.getColor() 
            ErrorLogger.debugLine("Parser:  foo.some_func()");
            result = new Expression(new DotOperatorToken(), leftSide, rightSide);
        }                 
        
        // check if the dot-expression is followed by another dot operator
        // (e.g. aaa.getGraphics().getSize().getValue() )
        if (peekNextToken(deliTyp) instanceof DotOperatorToken)
        {
            // push already parsed expression on stack
            operandStack.push(result);                  
            
            // remove "." from scanner
            getNextToken(deliTyp);                 
                                  
            // parse next dot-expression
            result = parseDotOperator(operandStack, deliTyp);  
        }     
             
        return result;
    }


    /***********************************************************************************/
    /** parse <function>(<operand>,<operand>,....) (e.g. min(3,4) )                    */
    /* @param FunctionToken                                                            */
    /* @param first parameter                                                            */
    /* @return parsed function (e.g. sin(3) or min(2,3) )                              */
    private OperandToken parseFunctionAndParameters(OperandToken nextToken, OperandToken firstParam)
    {
        // create new expression
        FunctionToken func = (FunctionToken)nextToken;

        // check if it is a special function e.g. "global a b c"
        if (func.getName().equals("global") || func.getName().equals("isglobal"))
        {
            ErrorLogger.debugLine("Parser: found global");
         
            // do not evaluate operands
            func.evaluationLockB=true;
            
            Token next = null ;
            while(true)
            {
                next      = peekNextToken();
                if (next==null)
                    break;
                    
                ErrorLogger.debugLine("Parser: global "+next.toString());
                
                if (next instanceof DelimiterToken)
                {
                    break;
                }
                else if (next instanceof VariableToken)
                {
                    ErrorLogger.debugLine("Parser: global variable "+next.toString());
                    getNextToken();
                    func.setOperands(new OperandToken[] {(OperandToken)next});
                }
                else
                    Errors.throwMathLibException("Parser: global");
            }
            
            // !!!! needs stack for multiple "global a b c e"
            //func.setOperands(new OperandToken[] {(OperandToken)next}); //parameters);
            return func;
        }
        
        
        // if next token is a "(" then ignore it
        Token next      = peekNextToken();
        
        // indicator if a cell array acess is parsed
        // e.g. a{4,6}='66'
        boolean cellB = false;
        
        if (isExpectedDelimiter( next, '(' ))
        {
            getNextToken();
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -