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:
andrei 2013-02-12 12:52:24 +00:00
parent e9eac89fcf
commit b269368c51
3 changed files with 52 additions and 27 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
};