streamlined filter syntax

This commit is contained in:
Marc Zinnschlag 2013-08-27 18:58:23 +02:00
parent 2e9948e86a
commit 26b3d93293
2 changed files with 47 additions and 43 deletions

View file

@ -174,14 +174,14 @@ CSMFilter::Token CSMFilter::Parser::checkKeywords (const Token& token)
{ {
"true", "false", "true", "false",
"and", "or", "not", "and", "or", "not",
"text", "value", "string", "value",
0 0
}; };
std::string string = Misc::StringUtils::lowerCase (token.mString); std::string string = Misc::StringUtils::lowerCase (token.mString);
for (int i=0; sKeywords[i]; ++i) for (int i=0; sKeywords[i]; ++i)
if (sKeywords[i]==string) if (sKeywords[i]==string || (string.size()==1 && sKeywords[i][0]==string[0]))
return Token (static_cast<Token::Type> (i+Token::Type_Keyword_True)); return Token (static_cast<Token::Type> (i+Token::Type_Keyword_True));
return token; return token;
@ -211,7 +211,7 @@ CSMFilter::Token CSMFilter::Parser::getNextToken()
case '[': ++mIndex; return Token (Token::Type_OpenSquare); case '[': ++mIndex; return Token (Token::Type_OpenSquare);
case ']': ++mIndex; return Token (Token::Type_CloseSquare); case ']': ++mIndex; return Token (Token::Type_CloseSquare);
case ',': ++mIndex; return Token (Token::Type_Comma); case ',': ++mIndex; return Token (Token::Type_Comma);
case '?': ++mIndex; return Token (Token::Type_OneShot); case '!': ++mIndex; return Token (Token::Type_OneShot);
} }
if (c=='"' || c=='_' || std::isalpha (c) || c==':') if (c=='"' || c=='_' || std::isalpha (c) || c==':')
@ -224,54 +224,58 @@ CSMFilter::Token CSMFilter::Parser::getNextToken()
return Token (Token::Type_None); return Token (Token::Type_None);
} }
boost::shared_ptr<CSMFilter::Node> CSMFilter::Parser::parseImp (bool allowEmpty) boost::shared_ptr<CSMFilter::Node> CSMFilter::Parser::parseImp (bool allowEmpty, bool ignoreOneShot)
{ {
if (Token token = getNextToken()) if (Token token = getNextToken())
{ {
switch (token.mType) if (token==Token (Token::Type_OneShot))
{ token = getNextToken();
case Token::Type_Keyword_True:
return boost::shared_ptr<CSMFilter::Node> (new BooleanNode (true)); if (token)
switch (token.mType)
case Token::Type_Keyword_False:
return boost::shared_ptr<CSMFilter::Node> (new BooleanNode (false));
case Token::Type_Keyword_And:
case Token::Type_Keyword_Or:
return parseNAry (token);
case Token::Type_Keyword_Not:
{ {
boost::shared_ptr<CSMFilter::Node> node = parseImp(); case Token::Type_Keyword_True:
return boost::shared_ptr<CSMFilter::Node> (new BooleanNode (true));
case Token::Type_Keyword_False:
return boost::shared_ptr<CSMFilter::Node> (new BooleanNode (false));
case Token::Type_Keyword_And:
case Token::Type_Keyword_Or:
return parseNAry (token);
case Token::Type_Keyword_Not:
{
boost::shared_ptr<CSMFilter::Node> node = parseImp();
if (mError)
return boost::shared_ptr<Node>();
return boost::shared_ptr<CSMFilter::Node> (new NotNode (node));
}
case Token::Type_Keyword_Text:
return parseText();
case Token::Type_Keyword_Value:
return parseValue();
case Token::Type_EOS:
if (!allowEmpty)
error();
if (mError)
return boost::shared_ptr<Node>(); return boost::shared_ptr<Node>();
return boost::shared_ptr<CSMFilter::Node> (new NotNode (node)); default:
}
case Token::Type_Keyword_Text:
return parseText();
case Token::Type_Keyword_Value:
return parseValue();
case Token::Type_EOS:
if (!allowEmpty)
error(); error();
}
return boost::shared_ptr<Node>();
default:
error();
}
} }
return boost::shared_ptr<Node>(); return boost::shared_ptr<Node>();
@ -528,7 +532,7 @@ bool CSMFilter::Parser::parse (const std::string& filter, bool allowPredefined)
if (!allowPredefined || token==Token (Token::Type_OneShot)) if (!allowPredefined || token==Token (Token::Type_OneShot))
{ {
boost::shared_ptr<Node> node = parseImp (true); boost::shared_ptr<Node> node = parseImp (true, token!=Token (Token::Type_OneShot));
if (mError) if (mError)
return false; return false;

View file

@ -31,7 +31,7 @@ namespace CSMFilter
Token checkKeywords (const Token& token); Token checkKeywords (const Token& token);
///< Turn string token into keyword token, if possible. ///< Turn string token into keyword token, if possible.
boost::shared_ptr<Node> parseImp (bool allowEmpty = false); boost::shared_ptr<Node> parseImp (bool allowEmpty = false, bool ignoreOneShot = false);
///< Will return a null-pointer, if there is nothing more to parse. ///< Will return a null-pointer, if there is nothing more to parse.
boost::shared_ptr<Node> parseNAry (const Token& keyword); boost::shared_ptr<Node> parseNAry (const Token& keyword);