зеркало из https://github.com/mozilla/gecko-dev.git
Bug 748365 - xpath: Don't progress past end in nextToken, remove pushBack() logic. r=sicking
This commit is contained in:
Родитель
a0dd043f0c
Коммит
74f0bb2104
|
@ -75,23 +75,25 @@ txExprLexer::~txExprLexer()
|
|||
Token*
|
||||
txExprLexer::nextToken()
|
||||
{
|
||||
NS_ASSERTION(mCurrentItem, "nextToken called beyoned the end");
|
||||
if (!mCurrentItem) {
|
||||
NS_NOTREACHED("nextToken called on uninitialized lexer");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (mCurrentItem->mType == Token::END) {
|
||||
// Do not progress beyond the end token
|
||||
return mCurrentItem;
|
||||
}
|
||||
|
||||
Token* token = mCurrentItem;
|
||||
mCurrentItem = mCurrentItem->mNext;
|
||||
return token;
|
||||
}
|
||||
|
||||
void
|
||||
txExprLexer::pushBack()
|
||||
{
|
||||
mCurrentItem = mCurrentItem ? mCurrentItem->mPrevious : mLastItem;
|
||||
}
|
||||
|
||||
void
|
||||
txExprLexer::addToken(Token* aToken)
|
||||
{
|
||||
if (mLastItem) {
|
||||
aToken->mPrevious = mLastItem;
|
||||
mLastItem->mNext = aToken;
|
||||
}
|
||||
if (!mFirstItem) {
|
||||
|
|
|
@ -128,16 +128,14 @@ public:
|
|||
: mStart(aStart),
|
||||
mEnd(aEnd),
|
||||
mType(aType),
|
||||
mNext(nsnull),
|
||||
mPrevious(nsnull)
|
||||
mNext(nsnull)
|
||||
{
|
||||
}
|
||||
Token(iterator aChar, Type aType)
|
||||
: mStart(aChar),
|
||||
mEnd(aChar + 1),
|
||||
mType(aType),
|
||||
mNext(nsnull),
|
||||
mPrevious(nsnull)
|
||||
mNext(nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -149,8 +147,6 @@ public:
|
|||
iterator mStart, mEnd;
|
||||
Type mType;
|
||||
Token* mNext;
|
||||
// XXX mPrevious needed for pushBack(), do we pushBack more than once?
|
||||
Token* mPrevious;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -186,12 +182,19 @@ public:
|
|||
Token* nextToken();
|
||||
Token* peek()
|
||||
{
|
||||
NS_ASSERTION(mCurrentItem, "peek called uninitialized lexer");
|
||||
return mCurrentItem;
|
||||
}
|
||||
void pushBack();
|
||||
Token* peekAhead()
|
||||
{
|
||||
NS_ASSERTION(mCurrentItem, "peekAhead called on uninitialized lexer");
|
||||
// Don't peek past the end node
|
||||
return (mCurrentItem && mCurrentItem->mNext) ? mCurrentItem->mNext : mCurrentItem;
|
||||
}
|
||||
bool hasMoreTokens()
|
||||
{
|
||||
return (mCurrentItem->mType != Token::END);
|
||||
NS_ASSERTION(mCurrentItem, "HasMoreTokens called on uninitialized lexer");
|
||||
return (mCurrentItem && mCurrentItem->mType != Token::END);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -337,9 +337,9 @@ txExprParser::createExpr(txExprLexer& lexer, txIParseContext* aContext,
|
|||
}
|
||||
}
|
||||
|
||||
Token* tok = lexer.nextToken();
|
||||
short tokPrecedence = precedence(tok);
|
||||
short tokPrecedence = precedence(lexer.peek());
|
||||
if (tokPrecedence != 0) {
|
||||
Token* tok = lexer.nextToken();
|
||||
while (!exprs.isEmpty() && tokPrecedence
|
||||
<= precedence(static_cast<Token*>(ops.peek()))) {
|
||||
// can't use expr as argument due to order of evaluation
|
||||
|
@ -357,7 +357,6 @@ txExprParser::createExpr(txExprLexer& lexer, txIParseContext* aContext,
|
|||
ops.push(tok);
|
||||
}
|
||||
else {
|
||||
lexer.pushBack();
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
@ -385,16 +384,16 @@ txExprParser::createFilterOrStep(txExprLexer& lexer, txIParseContext* aContext,
|
|||
*aResult = nsnull;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
Token* tok = lexer.nextToken();
|
||||
Token* tok = lexer.peek();
|
||||
|
||||
nsAutoPtr<Expr> expr;
|
||||
switch (tok->mType) {
|
||||
case Token::FUNCTION_NAME_AND_PAREN:
|
||||
lexer.pushBack();
|
||||
rv = createFunctionCall(lexer, aContext, getter_Transfers(expr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
break;
|
||||
case Token::VAR_REFERENCE :
|
||||
lexer.nextToken();
|
||||
{
|
||||
nsCOMPtr<nsIAtom> prefix, lName;
|
||||
PRInt32 nspace;
|
||||
|
@ -406,24 +405,26 @@ txExprParser::createFilterOrStep(txExprLexer& lexer, txIParseContext* aContext,
|
|||
}
|
||||
break;
|
||||
case Token::L_PAREN:
|
||||
lexer.nextToken();
|
||||
rv = createExpr(lexer, aContext, getter_Transfers(expr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (lexer.nextToken()->mType != Token::R_PAREN) {
|
||||
lexer.pushBack();
|
||||
if (lexer.peek()->mType != Token::R_PAREN) {
|
||||
return NS_ERROR_XPATH_PAREN_EXPECTED;
|
||||
}
|
||||
lexer.nextToken();
|
||||
break;
|
||||
case Token::LITERAL :
|
||||
lexer.nextToken();
|
||||
expr = new txLiteralExpr(tok->Value());
|
||||
break;
|
||||
case Token::NUMBER:
|
||||
{
|
||||
lexer.nextToken();
|
||||
expr = new txLiteralExpr(txDouble::toDouble(tok->Value()));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
lexer.pushBack();
|
||||
return createLocationStep(lexer, aContext, aResult);
|
||||
}
|
||||
|
||||
|
@ -582,9 +583,10 @@ txExprParser::createLocationStep(txExprLexer& lexer, txIParseContext* aContext,
|
|||
//-- get NodeTest unless an AbbreviatedStep was found
|
||||
nsresult rv = NS_OK;
|
||||
if (!nodeTest) {
|
||||
tok = lexer.nextToken();
|
||||
tok = lexer.peek();
|
||||
|
||||
if (tok->mType == Token::CNAME) {
|
||||
lexer.nextToken();
|
||||
// resolve QName
|
||||
nsCOMPtr<nsIAtom> prefix, lName;
|
||||
PRInt32 nspace;
|
||||
|
@ -600,7 +602,6 @@ txExprParser::createLocationStep(txExprLexer& lexer, txIParseContext* aContext,
|
|||
static_cast<PRUint16>(txXPathNodeType::ELEMENT_NODE));
|
||||
}
|
||||
else {
|
||||
lexer.pushBack();
|
||||
rv = createNodeTypeTest(lexer, getter_Transfers(nodeTest));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
@ -628,25 +629,29 @@ txExprParser::createNodeTypeTest(txExprLexer& lexer, txNodeTest** aTest)
|
|||
*aTest = 0;
|
||||
nsAutoPtr<txNodeTypeTest> nodeTest;
|
||||
|
||||
Token* nodeTok = lexer.nextToken();
|
||||
Token* nodeTok = lexer.peek();
|
||||
|
||||
switch (nodeTok->mType) {
|
||||
case Token::COMMENT_AND_PAREN:
|
||||
lexer.nextToken();
|
||||
nodeTest = new txNodeTypeTest(txNodeTypeTest::COMMENT_TYPE);
|
||||
break;
|
||||
case Token::NODE_AND_PAREN:
|
||||
lexer.nextToken();
|
||||
nodeTest = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE);
|
||||
break;
|
||||
case Token::PROC_INST_AND_PAREN:
|
||||
lexer.nextToken();
|
||||
nodeTest = new txNodeTypeTest(txNodeTypeTest::PI_TYPE);
|
||||
break;
|
||||
case Token::TEXT_AND_PAREN:
|
||||
lexer.nextToken();
|
||||
nodeTest = new txNodeTypeTest(txNodeTypeTest::TEXT_TYPE);
|
||||
break;
|
||||
default:
|
||||
lexer.pushBack();
|
||||
return NS_ERROR_XPATH_NO_NODE_TYPE_TEST;
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(nodeTest, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (nodeTok->mType == Token::PROC_INST_AND_PAREN &&
|
||||
|
@ -654,10 +659,10 @@ txExprParser::createNodeTypeTest(txExprLexer& lexer, txNodeTest** aTest)
|
|||
Token* tok = lexer.nextToken();
|
||||
nodeTest->setNodeName(tok->Value());
|
||||
}
|
||||
if (lexer.nextToken()->mType != Token::R_PAREN) {
|
||||
lexer.pushBack();
|
||||
if (lexer.peek()->mType != Token::R_PAREN) {
|
||||
return NS_ERROR_XPATH_PAREN_EXPECTED;
|
||||
}
|
||||
lexer.nextToken();
|
||||
|
||||
*aTest = nodeTest.forget();
|
||||
return NS_OK;
|
||||
|
@ -679,12 +684,11 @@ txExprParser::createPathExpr(txExprLexer& lexer, txIParseContext* aContext,
|
|||
|
||||
// is this a root expression?
|
||||
if (tok->mType == Token::PARENT_OP) {
|
||||
lexer.nextToken();
|
||||
if (!isLocationStepToken(lexer.peek())) {
|
||||
if (!isLocationStepToken(lexer.peekAhead())) {
|
||||
lexer.nextToken();
|
||||
*aResult = new RootExpr();
|
||||
return NS_OK;
|
||||
}
|
||||
lexer.pushBack();
|
||||
}
|
||||
|
||||
// parse first step (possibly a FilterExpr)
|
||||
|
@ -721,8 +725,7 @@ txExprParser::createPathExpr(txExprLexer& lexer, txIParseContext* aContext,
|
|||
// this is ugly
|
||||
while (1) {
|
||||
PathExpr::PathOperator pathOp;
|
||||
tok = lexer.nextToken();
|
||||
switch (tok->mType) {
|
||||
switch (lexer.peek()->mType) {
|
||||
case Token::ANCESTOR_OP :
|
||||
pathOp = PathExpr::DESCENDANT_OP;
|
||||
break;
|
||||
|
@ -730,11 +733,11 @@ txExprParser::createPathExpr(txExprLexer& lexer, txIParseContext* aContext,
|
|||
pathOp = PathExpr::RELATIVE_OP;
|
||||
break;
|
||||
default:
|
||||
lexer.pushBack();
|
||||
*aResult = pathExpr.forget();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
lexer.nextToken();
|
||||
|
||||
rv = createLocationStep(lexer, aContext, getter_Transfers(expr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -828,10 +831,10 @@ txExprParser::parsePredicates(PredicateList* aPredicateList,
|
|||
|
||||
expr.forget();
|
||||
|
||||
if (lexer.nextToken()->mType != Token::R_BRACKET) {
|
||||
lexer.pushBack();
|
||||
if (lexer.peek()->mType != Token::R_BRACKET) {
|
||||
return NS_ERROR_XPATH_BRACKET_EXPECTED;
|
||||
}
|
||||
lexer.nextToken();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -865,13 +868,14 @@ txExprParser::parseParameters(FunctionCall* aFnCall, txExprLexer& lexer,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
switch (lexer.nextToken()->mType) {
|
||||
switch (lexer.peek()->mType) {
|
||||
case Token::R_PAREN :
|
||||
lexer.nextToken();
|
||||
return NS_OK;
|
||||
case Token::COMMA: //-- param separator
|
||||
lexer.nextToken();
|
||||
break;
|
||||
default:
|
||||
lexer.pushBack();
|
||||
return NS_ERROR_XPATH_PAREN_EXPECTED;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -316,10 +316,11 @@ nsresult txPatternParser::createStepPattern(txExprLexer& aLexer,
|
|||
aLexer.nextToken();
|
||||
isAttr = true;
|
||||
}
|
||||
tok = aLexer.nextToken();
|
||||
|
||||
txNodeTest* nodeTest;
|
||||
if (tok->mType == Token::CNAME) {
|
||||
if (aLexer.peek()->mType == Token::CNAME) {
|
||||
tok = aLexer.nextToken();
|
||||
|
||||
// resolve QName
|
||||
nsCOMPtr<nsIAtom> prefix, lName;
|
||||
PRInt32 nspace;
|
||||
|
@ -339,7 +340,6 @@ nsresult txPatternParser::createStepPattern(txExprLexer& aLexer,
|
|||
}
|
||||
}
|
||||
else {
|
||||
aLexer.pushBack();
|
||||
rv = createNodeTypeTest(aLexer, &nodeTest);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче