Changed operators precedences.
Fixed postfix operators parse. git-svn-id: http://voip.null.ro/svn/yate@5402 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
e9eac89fcf
commit
b269368c51
|
@ -290,11 +290,21 @@ bool ExpEvaluator::getInstruction(const char*& expr, char stop, GenObject* neste
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ExpEvaluator::getOperand(const char*& expr, bool endOk)
|
||||
bool ExpEvaluator::getOperand(const char*& expr, bool endOk, int precedence)
|
||||
{
|
||||
if (inError())
|
||||
return false;
|
||||
XDebug(this,DebugAll,"getOperand '%.30s'",expr);
|
||||
if (!getOperandInternal(expr, endOk, precedence))
|
||||
return false;
|
||||
Opcode oper;
|
||||
while ((oper = getPostfixOperator(expr,precedence)) != OpcNone)
|
||||
addOpcode(oper);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExpEvaluator::getOperandInternal(const char*& expr, bool endOk, int precedence)
|
||||
{
|
||||
char c = skipComments(expr);
|
||||
if (!c)
|
||||
// end of string
|
||||
|
@ -310,7 +320,7 @@ bool ExpEvaluator::getOperand(const char*& expr, bool endOk)
|
|||
}
|
||||
Opcode op = getUnaryOperator(expr);
|
||||
if (op != OpcNone) {
|
||||
if (!getOperand(expr,false))
|
||||
if (!getOperand(expr,false,getPrecedence(op)))
|
||||
return false;
|
||||
addOpcode(op);
|
||||
return true;
|
||||
|
@ -480,7 +490,7 @@ ExpEvaluator::Opcode ExpEvaluator::getUnaryOperator(const char*& expr)
|
|||
return getOperator(expr,m_unaryOps);
|
||||
}
|
||||
|
||||
ExpEvaluator::Opcode ExpEvaluator::getPostfixOperator(const char*& expr)
|
||||
ExpEvaluator::Opcode ExpEvaluator::getPostfixOperator(const char*& expr, int priority)
|
||||
{
|
||||
return OpcNone;
|
||||
}
|
||||
|
@ -498,40 +508,41 @@ int ExpEvaluator::getPrecedence(ExpEvaluator::Opcode oper) const
|
|||
case OpcDecPre:
|
||||
case OpcIncPost:
|
||||
case OpcDecPost:
|
||||
return 120;
|
||||
case OpcNeg:
|
||||
case OpcNot:
|
||||
return 11;
|
||||
case OpcLNot:
|
||||
return 110;
|
||||
case OpcMul:
|
||||
case OpcDiv:
|
||||
case OpcMod:
|
||||
case OpcAnd:
|
||||
return 10;
|
||||
return 100;
|
||||
case OpcAdd:
|
||||
case OpcSub:
|
||||
case OpcOr:
|
||||
case OpcXor:
|
||||
return 9;
|
||||
return 90;
|
||||
case OpcShl:
|
||||
case OpcShr:
|
||||
return 8;
|
||||
return 80;
|
||||
case OpcCat:
|
||||
return 7;
|
||||
// ANY, ALL, SOME = 6
|
||||
case OpcLNot:
|
||||
return 5;
|
||||
return 70;
|
||||
// ANY, ALL, SOME = 60
|
||||
case OpcLt:
|
||||
case OpcGt:
|
||||
case OpcLe:
|
||||
case OpcGe:
|
||||
return 50;
|
||||
case OpcEq:
|
||||
case OpcNe:
|
||||
return 4;
|
||||
// IN, BETWEEN, LIKE, MATCHES = 3
|
||||
return 40;
|
||||
// IN, BETWEEN, LIKE, MATCHES = 30
|
||||
case OpcLAnd:
|
||||
return 2;
|
||||
return 20;
|
||||
case OpcLOr:
|
||||
case OpcLXor:
|
||||
return 1;
|
||||
return 10;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -157,7 +157,7 @@ protected:
|
|||
virtual bool getSimple(const char*& expr, bool constOnly = false);
|
||||
virtual Opcode getOperator(const char*& expr);
|
||||
virtual Opcode getUnaryOperator(const char*& expr);
|
||||
virtual Opcode getPostfixOperator(const char*& expr);
|
||||
virtual Opcode getPostfixOperator(const char*& expr, int precedence);
|
||||
virtual const char* getOperator(Opcode oper) const;
|
||||
virtual int getPrecedence(ExpEvaluator::Opcode oper) const;
|
||||
virtual bool getSeparator(const char*& expr, bool remove);
|
||||
|
@ -1483,12 +1483,14 @@ ExpEvaluator::Opcode JsCode::getUnaryOperator(const char*& expr)
|
|||
return ExpEvaluator::getUnaryOperator(expr);
|
||||
}
|
||||
|
||||
ExpEvaluator::Opcode JsCode::getPostfixOperator(const char*& expr)
|
||||
ExpEvaluator::Opcode JsCode::getPostfixOperator(const char*& expr, int precedence)
|
||||
{
|
||||
if (inError())
|
||||
return OpcNone;
|
||||
XDebug(this,DebugAll,"JsCode::getPostfixOperator '%.30s'",expr);
|
||||
if (skipComments(expr) == '[') {
|
||||
// The Indexing operator has maximum priority!
|
||||
// No need to check it.
|
||||
if (!runCompile(++expr,']'))
|
||||
return OpcNone;
|
||||
if (skipComments(expr) != ']') {
|
||||
|
@ -1499,10 +1501,17 @@ ExpEvaluator::Opcode JsCode::getPostfixOperator(const char*& expr)
|
|||
return (Opcode)OpcIndex;
|
||||
}
|
||||
skipComments(expr);
|
||||
const char* save = expr;
|
||||
unsigned int savedLine = m_lineNo;
|
||||
Opcode op = ExpEvaluator::getOperator(expr,s_postfixOps);
|
||||
if (OpcNone != op)
|
||||
return op;
|
||||
return ExpEvaluator::getPostfixOperator(expr);
|
||||
if (OpcNone != op) {
|
||||
if (getPrecedence(op) >= precedence)
|
||||
return op;
|
||||
expr = save;
|
||||
m_lineNo = savedLine;
|
||||
return OpcNone;
|
||||
}
|
||||
return ExpEvaluator::getPostfixOperator(expr,precedence);
|
||||
}
|
||||
|
||||
const char* JsCode::getOperator(Opcode oper) const
|
||||
|
@ -1532,13 +1541,14 @@ int JsCode::getPrecedence(ExpEvaluator::Opcode oper) const
|
|||
switch (oper) {
|
||||
case OpcEqIdentity:
|
||||
case OpcNeIdentity:
|
||||
return 4;
|
||||
case OpcNew:
|
||||
return 40;
|
||||
case OpcDelete:
|
||||
case OpcIndex:
|
||||
return 12;
|
||||
case OpcNew:
|
||||
case OpcTypeof:
|
||||
return 110;
|
||||
case OpcFieldOf:
|
||||
return 13;
|
||||
case OpcIndex:
|
||||
return 140;
|
||||
default:
|
||||
return ExpEvaluator::getPrecedence(oper);
|
||||
}
|
||||
|
@ -2107,6 +2117,7 @@ bool JsCode::runOperation(ObjList& stack, const ExpOperation& oper, GenObject* c
|
|||
obj->params().clearParam(name);
|
||||
ret = true;
|
||||
}
|
||||
DDebug(DebugAll,"Deleted '%s' : %s",name.c_str(),String::boolText(ret));
|
||||
pushOne(stack,new ExpOperation(ret));
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -545,9 +545,10 @@ protected:
|
|||
/**
|
||||
* Returns next unary postfix operator in the parsed text
|
||||
* @param expr Pointer to text to parse, gets advanced if succeeds
|
||||
* @param precedence The precedence of the previous operator
|
||||
* @return Operator code, OpcNone on failure
|
||||
*/
|
||||
virtual Opcode getPostfixOperator(const char*& expr);
|
||||
virtual Opcode getPostfixOperator(const char*& expr, int precedence = 0);
|
||||
|
||||
/**
|
||||
* Helper method to get the canonical name of an operator
|
||||
|
@ -591,9 +592,10 @@ protected:
|
|||
* Get an operand, advance parsing pointer past it
|
||||
* @param expr Pointer to text to parse, gets advanced on success
|
||||
* @param endOk Consider reaching the end of string a success
|
||||
* @param precedence The precedence of the previous operator
|
||||
* @return True if succeeded, must add the operand internally
|
||||
*/
|
||||
virtual bool getOperand(const char*& expr, bool endOk = true);
|
||||
virtual bool getOperand(const char*& expr, bool endOk = true, int precedence = 0);
|
||||
|
||||
/**
|
||||
* Get an inline simple type, usually string or number
|
||||
|
@ -803,6 +805,7 @@ protected:
|
|||
unsigned int m_lineNo;
|
||||
|
||||
private:
|
||||
bool getOperandInternal(const char*& expr, bool endOk, int precedence);
|
||||
ExpExtender* m_extender;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue