📄 parser.java
字号:
{
// 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 + -