mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Bug TW-1254
- TW-1254 Calc command can segfault on negative numbers (thanks to Renato Alves). - Implemented a recursive descent parser to syntax check the expression, and disambiguate unary minus. The syntax checking is not generating any diagnostics yet.
This commit is contained in:
parent
620f9b40b2
commit
70ba19fd5e
5 changed files with 424 additions and 21 deletions
|
@ -34,6 +34,8 @@ Bugs
|
||||||
- TD-42 Cannot compile taskd - GNUTLS_VERSION undefined in diag.cpp (thanks
|
- TD-42 Cannot compile taskd - GNUTLS_VERSION undefined in diag.cpp (thanks
|
||||||
to Michele Vetturi).
|
to Michele Vetturi).
|
||||||
- TD-45 Fix preprocessor define (thanks to Jochen Sprickerhof).
|
- TD-45 Fix preprocessor define (thanks to Jochen Sprickerhof).
|
||||||
|
- TW-1254 Calc command can segfault on negative numbers (thanks to Renato
|
||||||
|
Alves).
|
||||||
- TW-1282 incorrect URLs in man task-sync (thanks to Jeremiah Marks).
|
- TW-1282 incorrect URLs in man task-sync (thanks to Jeremiah Marks).
|
||||||
- TW-1288 Added missing locking for task modifications (thanks to Kosta H,
|
- TW-1288 Added missing locking for task modifications (thanks to Kosta H,
|
||||||
Ralph Bean, Adam Coddington).
|
Ralph Bean, Adam Coddington).
|
||||||
|
|
424
src/Eval.cpp
424
src/Eval.cpp
|
@ -40,32 +40,38 @@ static struct
|
||||||
} operators[] =
|
} operators[] =
|
||||||
{
|
{
|
||||||
// Operator Precedence Type Associativity
|
// Operator Precedence Type Associativity
|
||||||
{ "and", 5, 'b', 'l' }, // Conjunction
|
|
||||||
{ "xor", 4, 'b', 'l' }, // Disjunction
|
|
||||||
|
|
||||||
{ "or", 3, 'b', 'l' }, // Disjunction
|
|
||||||
{ "<=", 10, 'b', 'l' }, // Less than or equal
|
|
||||||
{ ">=", 10, 'b', 'l' }, // Greater than or equal
|
|
||||||
{ "!~", 9, 'b', 'l' }, // Regex non-match
|
|
||||||
{ "!=", 9, 'b', 'l' }, // Inequal
|
|
||||||
|
|
||||||
{ "==", 9, 'b', 'l' }, // Equal
|
|
||||||
{ "=", 9, 'b', 'l' }, // Equal
|
|
||||||
{ "^", 16, 'b', 'r' }, // Exponent
|
{ "^", 16, 'b', 'r' }, // Exponent
|
||||||
{ ">", 10, 'b', 'l' }, // Greater than
|
|
||||||
{ "~", 9, 'b', 'l' }, // Regex match
|
|
||||||
{ "!", 15, 'u', 'r' }, // Not
|
|
||||||
|
|
||||||
{ "_hastag_", 9, 'b', 'l'}, // +tag [Pseudo-op]
|
{ "!", 15, 'u', 'r' }, // Unary not
|
||||||
{ "_notag_", 9, 'b', 'l'}, // -tag [Pseudo-op]
|
{ "_neg_", 15, 'u', 'r' }, // Unary minus
|
||||||
|
{ "_pos_", 15, 'u', 'r' }, // Unary plus
|
||||||
|
|
||||||
|
{ "_hastag_", 14, 'b', 'l'}, // +tag [Pseudo-op]
|
||||||
|
{ "_notag_", 14, 'b', 'l'}, // -tag [Pseudo-op]
|
||||||
|
|
||||||
{ "-", 15, 'u', 'r' }, // Unary minus
|
|
||||||
{ "*", 13, 'b', 'l' }, // Multiplication
|
{ "*", 13, 'b', 'l' }, // Multiplication
|
||||||
{ "/", 13, 'b', 'l' }, // Division
|
{ "/", 13, 'b', 'l' }, // Division
|
||||||
{ "%", 13, 'b', 'l' }, // Modulus
|
{ "%", 13, 'b', 'l' }, // Modulus
|
||||||
|
|
||||||
{ "+", 12, 'b', 'l' }, // Addition
|
{ "+", 12, 'b', 'l' }, // Addition
|
||||||
{ "-", 12, 'b', 'l' }, // Subtraction
|
{ "-", 12, 'b', 'l' }, // Subtraction
|
||||||
|
|
||||||
|
{ "<=", 10, 'b', 'l' }, // Less than or equal
|
||||||
|
{ ">=", 10, 'b', 'l' }, // Greater than or equal
|
||||||
|
{ ">", 10, 'b', 'l' }, // Greater than
|
||||||
{ "<", 10, 'b', 'l' }, // Less than
|
{ "<", 10, 'b', 'l' }, // Less than
|
||||||
|
|
||||||
|
{ "=", 9, 'b', 'l' }, // Equal
|
||||||
|
{ "==", 9, 'b', 'l' }, // Equal
|
||||||
|
{ "!=", 9, 'b', 'l' }, // Inequal
|
||||||
|
|
||||||
|
{ "~", 8, 'b', 'l' }, // Regex match
|
||||||
|
{ "!~", 8, 'b', 'l' }, // Regex non-match
|
||||||
|
|
||||||
|
{ "and", 5, 'b', 'l' }, // Conjunction
|
||||||
|
{ "or", 4, 'b', 'l' }, // Disjunction
|
||||||
|
{ "xor", 3, 'b', 'l' }, // Disjunction
|
||||||
|
|
||||||
{ "(", 0, 'b', 'l' }, // Precedence start
|
{ "(", 0, 'b', 'l' }, // Precedence start
|
||||||
{ ")", 0, 'b', 'l' }, // Precedence end
|
{ ")", 0, 'b', 'l' }, // Precedence end
|
||||||
};
|
};
|
||||||
|
@ -106,6 +112,9 @@ void Eval::evaluateInfixExpression (const std::string& e, Variant& v) const
|
||||||
std::cout << "# token infix '" << token << "' " << Lexer::type_name (type) << "\n";
|
std::cout << "# token infix '" << token << "' " << Lexer::type_name (type) << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse for syntax checking and operator replacement.
|
||||||
|
infixParse (tokens);
|
||||||
|
|
||||||
// Convert infix --> postfix.
|
// Convert infix --> postfix.
|
||||||
infixToPostfix (tokens);
|
infixToPostfix (tokens);
|
||||||
|
|
||||||
|
@ -163,7 +172,7 @@ void Eval::evaluatePostfixStack (
|
||||||
std::vector <std::pair <std::string, Lexer::Type> >::const_iterator token;
|
std::vector <std::pair <std::string, Lexer::Type> >::const_iterator token;
|
||||||
for (token = tokens.begin (); token != tokens.end (); ++token)
|
for (token = tokens.begin (); token != tokens.end (); ++token)
|
||||||
{
|
{
|
||||||
// Unary operator.
|
// Unary operators.
|
||||||
if (token->second == Lexer::typeOperator &&
|
if (token->second == Lexer::typeOperator &&
|
||||||
token->first == "!")
|
token->first == "!")
|
||||||
{
|
{
|
||||||
|
@ -171,6 +180,18 @@ void Eval::evaluatePostfixStack (
|
||||||
values.pop_back ();
|
values.pop_back ();
|
||||||
values.push_back (! right);
|
values.push_back (! right);
|
||||||
}
|
}
|
||||||
|
else if (token->second == Lexer::typeOperator &&
|
||||||
|
token->first == "_neg_")
|
||||||
|
{
|
||||||
|
Variant right = values.back ();
|
||||||
|
values.pop_back ();
|
||||||
|
values.push_back (Variant (0) - right);
|
||||||
|
}
|
||||||
|
else if (token->second == Lexer::typeOperator &&
|
||||||
|
token->first == "_pos_")
|
||||||
|
{
|
||||||
|
// NOP?
|
||||||
|
}
|
||||||
|
|
||||||
// Binary operators.
|
// Binary operators.
|
||||||
else if (token->second == Lexer::typeOperator)
|
else if (token->second == Lexer::typeOperator)
|
||||||
|
@ -279,6 +300,373 @@ void Eval::evaluatePostfixStack (
|
||||||
result = values[0];
|
result = values[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Grammar:
|
||||||
|
// Logical --> Regex {( "and" | "or" | "xor" ) Regex}
|
||||||
|
// Regex --> Equality {( "~" | "!~" ) Equality}
|
||||||
|
// Equality --> Comparative {( "==" | "=" | "!=" ) Comparative}
|
||||||
|
// Comparative --> Arithmetic {( "<=" | "<" | ">=" | ">" ) Arithmetic}
|
||||||
|
// Arithmetic --> Geometric {( "+" | "-" ) Geometric}
|
||||||
|
// Geometric --> Tag {( "*" | "/" | "%" ) Tag}
|
||||||
|
// Tag --> Unary {( "_hastag_" | "_notag_" ) Unary}
|
||||||
|
// Unary --> [( "-" | "+" | "!" )] Exponent
|
||||||
|
// Exponent --> Primitive ["^" Primitive]
|
||||||
|
// Primitive --> "(" Logical ")" | Variant
|
||||||
|
//
|
||||||
|
void Eval::infixParse (
|
||||||
|
std::vector <std::pair <std::string, Lexer::Type> >& infix) const
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# infixParse\n";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
if (parseLogical (infix, i))
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# no errors.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (const std::string& error)
|
||||||
|
{
|
||||||
|
std::cerr << error << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
std::cerr << "Unknown error.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Logical --> Regex {( "and" | "or" | "xor" ) Regex}
|
||||||
|
bool Eval::parseLogical (
|
||||||
|
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||||
|
int &i) const
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# parseLogical\n";
|
||||||
|
|
||||||
|
if (i < infix.size () &&
|
||||||
|
parseRegex (infix, i))
|
||||||
|
{
|
||||||
|
while ((infix[i].first == "and" ||
|
||||||
|
infix[i].first == "or" ||
|
||||||
|
infix[i].first == "xor") &&
|
||||||
|
infix[i].second == Lexer::typeOperator)
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# " << infix[i].first << "\n";
|
||||||
|
|
||||||
|
++i;
|
||||||
|
if (! parseRegex (infix, i))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Regex --> Equality {( "~" | "!~" ) Equality}
|
||||||
|
bool Eval::parseRegex (
|
||||||
|
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||||
|
int &i) const
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# parseRegex\n";
|
||||||
|
|
||||||
|
if (i < infix.size () &&
|
||||||
|
parseEquality (infix, i))
|
||||||
|
{
|
||||||
|
while ((infix[i].first == "~" ||
|
||||||
|
infix[i].first == "!~") &&
|
||||||
|
infix[i].second == Lexer::typeOperator)
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# " << infix[i].first << "\n";
|
||||||
|
|
||||||
|
++i;
|
||||||
|
if (! parseEquality (infix, i))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Equality --> Comparative {( "==" | "=" | "!=" ) Comparative}
|
||||||
|
bool Eval::parseEquality (
|
||||||
|
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||||
|
int &i) const
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# parseEquality\n";
|
||||||
|
|
||||||
|
if (i < infix.size () &&
|
||||||
|
parseComparative (infix, i))
|
||||||
|
{
|
||||||
|
while ((infix[i].first == "==" ||
|
||||||
|
infix[i].first == "=" ||
|
||||||
|
infix[i].first == "!=") &&
|
||||||
|
infix[i].second == Lexer::typeOperator)
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# " << infix[i].first << "\n";
|
||||||
|
|
||||||
|
++i;
|
||||||
|
if (! parseComparative (infix, i))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Comparative --> Arithmetic {( "<=" | "<" | ">=" | ">" ) Arithmetic}
|
||||||
|
bool Eval::parseComparative (
|
||||||
|
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||||
|
int &i) const
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# parseComparative\n";
|
||||||
|
|
||||||
|
if (i < infix.size () &&
|
||||||
|
parseArithmetic (infix, i))
|
||||||
|
{
|
||||||
|
while ((infix[i].first == "<=" ||
|
||||||
|
infix[i].first == "<" ||
|
||||||
|
infix[i].first == ">=" ||
|
||||||
|
infix[i].first == ">") &&
|
||||||
|
infix[i].second == Lexer::typeOperator)
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# " << infix[i].first << "\n";
|
||||||
|
|
||||||
|
++i;
|
||||||
|
if (! parseArithmetic (infix, i))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Arithmetic --> Geometric {( "+" | "-" ) Geometric}
|
||||||
|
bool Eval::parseArithmetic (
|
||||||
|
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||||
|
int &i) const
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# parseArithmetic\n";
|
||||||
|
|
||||||
|
if (i < infix.size () &&
|
||||||
|
parseGeometric (infix, i))
|
||||||
|
{
|
||||||
|
while ((infix[i].first == "+" ||
|
||||||
|
infix[i].first == "-") &&
|
||||||
|
infix[i].second == Lexer::typeOperator)
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# " << infix[i].first << "\n";
|
||||||
|
|
||||||
|
++i;
|
||||||
|
if (! parseGeometric (infix, i))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Geometric --> Tag {( "*" | "/" | "%" ) Tag}
|
||||||
|
bool Eval::parseGeometric (
|
||||||
|
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||||
|
int &i) const
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# parseGeometric\n";
|
||||||
|
|
||||||
|
if (i < infix.size () &&
|
||||||
|
parseTag (infix, i))
|
||||||
|
{
|
||||||
|
while ((infix[i].first == "*" ||
|
||||||
|
infix[i].first == "/" ||
|
||||||
|
infix[i].first == "%") &&
|
||||||
|
infix[i].second == Lexer::typeOperator)
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# " << infix[i].first << "\n";
|
||||||
|
|
||||||
|
++i;
|
||||||
|
if (! parseTag (infix, i))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Tag --> Unary {( "_hastag_" | "_notag_" ) Unary}
|
||||||
|
bool Eval::parseTag (
|
||||||
|
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||||
|
int &i) const
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# parseTag\n";
|
||||||
|
|
||||||
|
if (i < infix.size () &&
|
||||||
|
parseUnary (infix, i))
|
||||||
|
{
|
||||||
|
while ((infix[i].first == "_hastag_" ||
|
||||||
|
infix[i].first == "_notag_") &&
|
||||||
|
infix[i].second == Lexer::typeOperator)
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# " << infix[i].first << "\n";
|
||||||
|
|
||||||
|
++i;
|
||||||
|
if (! parseUnary (infix, i))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Unary --> [( "-" | "+" | "!" )] Exponent
|
||||||
|
bool Eval::parseUnary (
|
||||||
|
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||||
|
int &i) const
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# parseUnary\n";
|
||||||
|
|
||||||
|
if (i < infix.size ())
|
||||||
|
{
|
||||||
|
if (infix[i].first == "-")
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# '-' --> '_neg_'\n";
|
||||||
|
|
||||||
|
infix[i].first = "_neg_";
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
else if (infix[i].first == "+")
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# '+' --> '_pos_'\n";
|
||||||
|
|
||||||
|
infix[i].first = "_pos_";
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
else if (infix[i].first == "!")
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# " << infix[i].first << "\n";
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseExponent (infix, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Exponent --> Primitive ["^" Primitive]
|
||||||
|
bool Eval::parseExponent (
|
||||||
|
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||||
|
int &i) const
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# parseExponent\n";
|
||||||
|
|
||||||
|
if (i < infix.size () &&
|
||||||
|
parsePrimitive (infix, i))
|
||||||
|
{
|
||||||
|
while (infix[i].first == "^" &&
|
||||||
|
infix[i].second == Lexer::typeOperator)
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# " << infix[i].first << "\n";
|
||||||
|
|
||||||
|
++i;
|
||||||
|
if (! parsePrimitive (infix, i))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Primitive --> "(" Logical ")" | Variant
|
||||||
|
bool Eval::parsePrimitive (
|
||||||
|
std::vector <std::pair <std::string, Lexer::Type> >& infix,
|
||||||
|
int &i) const
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# parseVariant\n";
|
||||||
|
|
||||||
|
if (i < infix.size ())
|
||||||
|
{
|
||||||
|
if (infix[i].first == "(")
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# " << infix[i].first << "\n";
|
||||||
|
|
||||||
|
++i;
|
||||||
|
if (parseLogical (infix, i))
|
||||||
|
{
|
||||||
|
if (i < infix.size () &&
|
||||||
|
infix[i].first == ")")
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# " << infix[i].first << "\n";
|
||||||
|
|
||||||
|
++i;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (infix[i].second != Lexer::typeOperator)
|
||||||
|
{
|
||||||
|
if (_debug)
|
||||||
|
std::cout << "# " << infix[i].first << "\n";
|
||||||
|
|
||||||
|
++i;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Dijkstra Shunting Algorithm.
|
// Dijkstra Shunting Algorithm.
|
||||||
// http://en.wikipedia.org/wiki/Shunting-yard_algorithm
|
// http://en.wikipedia.org/wiki/Shunting-yard_algorithm
|
||||||
|
|
11
src/Eval.h
11
src/Eval.h
|
@ -50,6 +50,17 @@ public:
|
||||||
private:
|
private:
|
||||||
void evaluatePostfixStack (const std::vector <std::pair <std::string, Lexer::Type> >&, Variant&) const;
|
void evaluatePostfixStack (const std::vector <std::pair <std::string, Lexer::Type> >&, Variant&) const;
|
||||||
void infixToPostfix (std::vector <std::pair <std::string, Lexer::Type> >&) const;
|
void infixToPostfix (std::vector <std::pair <std::string, Lexer::Type> >&) const;
|
||||||
|
void infixParse (std::vector <std::pair <std::string, Lexer::Type> >&) const;
|
||||||
|
bool parseLogical (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||||
|
bool parseRegex (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||||
|
bool parseEquality (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||||
|
bool parseComparative (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||||
|
bool parseArithmetic (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||||
|
bool parseGeometric (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||||
|
bool parseTag (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||||
|
bool parseUnary (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||||
|
bool parseExponent (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||||
|
bool parsePrimitive (std::vector <std::pair <std::string, Lexer::Type> >&, int &) const;
|
||||||
bool identifyOperator (const std::string&, char&, int&, char&) const;
|
bool identifyOperator (const std::string&, char&, int&, char&) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <cmake.h>
|
#include <cmake.h>
|
||||||
|
//#include <iostream> // TODO Remove
|
||||||
#include <ISO8601.h>
|
#include <ISO8601.h>
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -755,9 +756,9 @@ void ISO8601d::resolve ()
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/*
|
|
||||||
void ISO8601d::dump ()
|
void ISO8601d::dump ()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
std::cout << "# Y=" << _year
|
std::cout << "# Y=" << _year
|
||||||
<< " M=" << _month
|
<< " M=" << _month
|
||||||
<< " W=" << _week
|
<< " W=" << _week
|
||||||
|
@ -770,8 +771,8 @@ void ISO8601d::dump ()
|
||||||
<< " ambi=" << _ambiguity
|
<< " ambi=" << _ambiguity
|
||||||
<< " --> " << _value
|
<< " --> " << _value
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
ISO8601p::ISO8601p ()
|
ISO8601p::ISO8601p ()
|
||||||
|
|
|
@ -59,6 +59,7 @@ private:
|
||||||
int dayOfWeek (int, int, int);
|
int dayOfWeek (int, int, int);
|
||||||
bool validate ();
|
bool validate ();
|
||||||
void resolve ();
|
void resolve ();
|
||||||
|
void dump ();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool _ambiguity;
|
bool _ambiguity;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue