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

📄 parser.java

📁 JAVA 数学程序库 提供常规的数值计算程序包
💻 JAVA
📖 第 1 页 / 共 5 页
字号:

            // throw exception for multiple operands
            // e.g. a=/7  a=*8  +*5  -*8  -/9
            if (( (nextToken  instanceof AssignmentOperatorToken) ||
                  (nextToken  instanceof AddSubOperatorToken)     ||
                  (nextToken  instanceof MulDivOperatorToken)        ) &&
                (pToken     instanceof MulDivOperatorToken)               )
                Errors.throwParserException("multiple operators * /");

            // e.g. a=^7  +^3  -^6  *^5  ^^5  !^7
            if (( (nextToken  instanceof AssignmentOperatorToken) ||
                  (nextToken  instanceof AddSubOperatorToken)     ||
                  (nextToken  instanceof PowerOperatorToken)        ) &&
                (pToken     instanceof PowerOperatorToken)                )
                Errors.throwParserException("multiple operators ^");

            
            ErrorLogger.debugLine("PARSER  op+op: "+pToken);
            ErrorLogger.debugLine("PARSER  op+op: "+nextToken);
            
        	if(nextToken instanceof AssignmentOperatorToken)
            {
                ErrorLogger.debugLine("Parser: <x> = <y>");
                retToken = parseAssignmentOperator(nextToken, operandStack);                    
            }
            else if(nextToken instanceof ColonOperatorToken)
            {
                ErrorLogger.debugLine("Parser: <x> : <y>");
                retToken = parseColonOperator(nextToken, operandStack);                    
            }
            else if(nextToken instanceof DotOperatorToken)
            {                    
                ErrorLogger.debugLine("Parser: dot-operator");
                retToken  = parseDotOperator(operandStack, deliTyp);
            }
            else if(    (nextToken instanceof AddSubOperatorToken)
                     || (nextToken instanceof MulDivOperatorToken)
                     || (nextToken instanceof PowerOperatorToken)
                     || (nextToken instanceof BinaryOperatorToken)
                     || (nextToken instanceof RelationOperatorToken))
            {    
                /* Binary tokens: +, -, *, /, ^, <=, >=, ~=, == */
                ErrorLogger.debugLine("Parser: <x> " + nextToken.toString() + " <y>");
                retToken = parseBinaryOperator(nextToken, operandStack);                    
            }
            else if(nextToken instanceof UnaryOperatorToken)
            {
                ErrorLogger.debugLine("Parser: unary operator "+nextToken.toString());
                retToken = parseUnaryOperator(nextToken, operandStack);                    
            }
        }
        else 
        { 
            // every valid token must have been analyzed above
            Errors.throwParserException(" unknown token: "+peekToken.toString());
        }

        ErrorLogger.decreaseIndent();
        if (retToken!=null) ErrorLogger.debugLine("Parser return: " + retToken.toString());
        else                ErrorLogger.debugLine("Parser return: null");
        
        return retToken;
    } // end parseSingle
 

    /**parse the expression contained in exp, this method is also called recursivly 
       to find the parameters of functions and matrices  (e.g. something like 2+3+(2*4) )
     @param  deliTyp indicates if an argument is part of a matrix (whitespaces are treated
             as delimiters in this case)
     @return expression (e.g. 3 or 2+3 or sin(cos(3)) ) */
    private OperandToken parseArithExpression(int deliTyp)
    {
        
        // expressions have their own stack
        Stack operandStack = new Stack(); 
        
        ErrorLogger.debugLine("Parser parseArithmeticExpr begin");
        ErrorLogger.increaseIndent();

        while(true)
        {
            // parsing is not useful if the next token will be a closing ")"
            // (e.g. who() or a.getColor() )
            if ( isExpectedDelimiter(peekNextToken(deliTyp), ')') )
                break;
            
            // parse next token
            OperandToken subExpr = parseSingle(operandStack, deliTyp);         

            // Put parsed token on the operand stack
            // If nothing useful was parsed then break
            if (subExpr != null)
                operandStack.push(subExpr);

            Token peekToken = peekNextToken(deliTyp);
            
            // arithmetic expressions are terminated by the following delimiters
            if(peekToken instanceof DelimiterToken)
            {
                DelimiterToken token = ((DelimiterToken)peekToken);

                // check wether or not the next token is a closing delimiter
                if ( (token.value == ',')  || (token.value == ';')  ||  
                     (token.value == '\r') || (token.value == '\n') || 
                     (token.value == '}')  || (token.value == '-')  || 
                     (token.value == ' ')  || (token.value == ')')  || 
                     (token.value == ']')                               ) 
                 {
                     ErrorLogger.debugLine("Parser delimiter break "+token.value);
                     break;   
                 }
                    
            }
            
            
            // if no more tokens are available return
            if(peekToken==null)
                break;
            
        } // end while
    
    
        // Check if the currently parsed expression is terminated by a delimiter
        //  which has the display property.     
        //  (e.g: display "a=4,"  don't display "a=4;")
        //if ((getCurrentToken() instanceof DelimiterToken) &&
        //    isDisplayResultToken(getCurrentToken())       &&
        //    !operandStack.isEmpty())
        //{
        //      OperandToken op = (OperandToken)operandStack.pop();
        //    ErrorLogger.debugLine("Parser: display true "+op.toString());
        //    op.setDisplayResult(true);
        //    operandStack.push(op);
        //}

        
        // build return token
        OperandToken retT = null;
        if (!operandStack.isEmpty())
            retT = (OperandToken)operandStack.pop();
            
        // throw error if stacksize > 1
    
        ErrorLogger.decreaseIndent();
        ErrorLogger.debugLine("Parser parseArithmeticExpr end ");
            
        return retT;
    }

    /** parse a list of commands (e.g. a=2+3;if(a=2){b=3};c=sin(pi) )
    @return OperantToken tree of operand tokens (e.g. a=2+3) */
    private OperandToken parseCommandList()
    {
        // these could be concatenated expressions (e.g.: "a=1;b=sin(4);c=3")
        ErrorLogger.debugLine("Parser parseCommandList begin");
        ErrorLogger.increaseIndent();

        Stack operandStack   = new Stack();

        OperandToken command;
        while (true) 
        {
        
            // parse next token/command
        	ErrorLogger.debugLine("Parser parseCommandList next");
            //command = parseSingle(operandStack, SINGLE);
        	
            // handling of {...} for commands is done here only, there has
        	//   to be a difference in order to parse cell arrays
            if (isExpectedDelimiter(peekNextToken(), '{' ))
            {
    	        getNextToken();
            	// get commands inside {...}
            	// get commands (e.g. if(3) ... endif  or  if(3) ... elseif
    	        command = parseCommandList();    
    	        
    	        if (!isExpectedDelimiter( peekNextToken(), '}' ))
                    Errors.throwParserException(" parseCommandList ERROR missing }");
                else
                    getNextToken();
            }
            else
            	command = parseSingle(operandStack, SINGLE);
        	

            
            Token peekToken = peekNextToken();
            
            // Check if the currently parsed expression will be terminated by a delimiter
            //  which has the display property.     
            //  (e.g: display "a=4,"  don't display "a=4;")
            if (isDisplayResultToken(peekToken) && (command != null))
            {
                ErrorLogger.debugLine("Parser: display true "+command.toString());
                command.setDisplayResult(true);
            }
            
            // put parsed token on the operand stack
            if (command != null)
                operandStack.push(command);
            
            // Check if the token, why the parser is returned is correct
            // Command lists are terminated by "}" "endif" "end" "else"
            if (    isExpectedDelimiter(peekToken, "elseif")      ||
            		isExpectedDelimiter(peekToken, "else")        ||
    				isExpectedDelimiter(peekToken, "endif")       ||
    				isExpectedDelimiter(peekToken, "end")         ||
    				isExpectedDelimiter(peekToken, "endfunction") ||
    				isExpectedDelimiter(peekToken, "case")        ||
    				isExpectedDelimiter(peekToken, "default")     ||
    				isExpectedDelimiter(peekToken, "otherwise")   ||
    				isExpectedDelimiter(peekToken, "endswitch")   ||
    				isExpectedDelimiter(peekToken, "endwhile")    ||
    				isExpectedDelimiter(peekToken, "endfor")      ||
					isExpectedDelimiter(peekToken, '}')              )
            {
                // this path is only called from parseSingle( .. parseCommandList() )
            	ErrorLogger.debugLine("Parser parseCommandList break");
            	break;
            }
            else if (isExpectedDelimiter(peekToken, ',')  ||
            	     isExpectedDelimiter(peekToken, ';')  ||
				     isExpectedDelimiter(peekToken, '\r') ||
				     isExpectedDelimiter(peekToken, '\n')    )
            {
                // remove delimiters from parseSingle
            	getNextToken();
            }
            else  if (peekToken == null) 
            {
            	// command lists may be terminated by end of file 
                break;
            }
            else
            {
            	// is none of the above delimiters occured, there is an
            	//    error e.g. ceil(5;8]
            	//Errors.throwParserException("parseCommandList wrong delimiter");
            	//break;
            }
            	
        } // end while
        
        // put all code parts from the stack into one expression object    
        OperandToken tree      = null;
        int          stackSize = operandStack.size();
        if (stackSize > 0)
        {
            //The expressions have been put onto the stack in reversed order
            OperandToken[] opTokenArray = new OperandToken[stackSize];
            for(int i=stackSize-1; i>=0; i--)
            {
                OperandToken ob = ((OperandToken)operandStack.pop());
                   opTokenArray[i] = ob;
            }
            tree = new Expression(null, opTokenArray, stackSize);
        }

        ErrorLogger.decreaseIndent();
        ErrorLogger.debugLine("Parser parseCommandList end");
        return tree;
    }

/***************************************************************************************/
/*****             individual parsing methods                                     ******/
/***************************************************************************************/

    /** parse <variable><=><operand> (e.g. a=3 or a=2+3+4 or [a,b]=step(x) )           */                  
    /* @param                             				                                 */
    /* @param                                                                          */
    /* @return expression of assignment (e.g. a=3)                                     */
    private OperandToken parseAssignmentOperator(Token currentToken, Stack operandStack)
    {
        // operator    (this should be a "=")
        OperatorToken operator = (OperatorToken)currentToken; 
        
        //parse right parameter                    
        OperandToken rightSide = parseArithExpression(SINGLE);     

        //get left parameter from operandStack (e.g. a or [a,b,c]  =...)                
        OperandToken leftSide = (OperandToken)operandStack.pop(); 

        /* create new expression */
        Expression tree = new Expression(operator, leftSide, rightSide);

        return tree;
    } // end parseAssignmentOperator


    /***********************************************************************************/
    /** parse <operand>:<operand>           (e.g. 2:7 -> [2,3,4,5,6,7])                */
    /** parse <operand>:<operand>:<operand> (e.g. 2:3:8 -> [2,5,8]                     */
    /* @param                                                                            */
    /* @param                                                                           */
    /* @return                                                                         */
    private OperandToken parseColonOperator(Token nextToken, Stack operandStack)
    {
        OperandToken leftSide = null;

        //get left parameter from operandStack                    
        if(!operandStack.isEmpty())     
            leftSide =(OperandToken)operandStack.pop(); 

        //parse right parameter                    
        //be careful about e.g. a(:), a(1,:)
        OperandToken rightSide = null;
        if (!isExpectedDelimiter(peekNextToken(), ')') &&
            !isExpectedDelimiter(peekNextToken(), ',') &&
            !isExpectedDelimiter(peekNextToken(), ';')    ) 
            rightSide = parseArithExpression(SINGLE);     
        else
            rightSide = null;
        
        // also possible is something like a(1:end) or a(2:4:end)
        if (isExpectedDelimiter(peekNextToken(), "end"))
            rightSide = (OperandToken)getNextToken();

        // Check is left Side is empty
        if ((leftSide==null)                     || 
            (leftSide instanceof DelimiterToken)    )

⌨️ 快捷键说明

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