mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-08-20 13:23:08 +02:00
Expressions
- Began Expression::toInfix to upgrade old-style filters to infix algebraic filters. - Added operator support to Arguments::categorize. - Modified CmdCustom.cpp as a read-only command guinea-pig for the new argument processing.
This commit is contained in:
parent
68a749ee16
commit
86dcec8aea
6 changed files with 98 additions and 11 deletions
|
@ -40,7 +40,7 @@
|
|||
|
||||
extern Context context;
|
||||
|
||||
// Synonyms on the same line.
|
||||
// Supported modifiers, synonyms on the same line.
|
||||
static const char* modifierNames[] =
|
||||
{
|
||||
"before", "under", "below",
|
||||
|
@ -57,7 +57,31 @@ static const char* modifierNames[] =
|
|||
"noword"
|
||||
};
|
||||
|
||||
// Supported operators, synonyms on same line.
|
||||
static const char* operators[] =
|
||||
{
|
||||
"+", // Addition, unary plus
|
||||
"-", // Subtraction, unary minus
|
||||
"*", // Multiplication
|
||||
"/", // Division
|
||||
"%", // Modulus
|
||||
"~", // Substring/regex match
|
||||
"!~", // Substring/regex no-match
|
||||
"<", "lt", // Less than
|
||||
"<=", "le", // Less than or equal
|
||||
"=", "eq", // Equal
|
||||
"!=", "ne", // Not equal
|
||||
">=", "ge", // Greater than or equal
|
||||
">", "gt", // Greater than
|
||||
"!", "not", // Not
|
||||
"and", // Conjunction
|
||||
"or", // Disjunction
|
||||
"(", // Precedence start
|
||||
")" // Precedence end
|
||||
};
|
||||
|
||||
#define NUM_MODIFIER_NAMES (sizeof (modifierNames) / sizeof (modifierNames[0]))
|
||||
#define NUM_OPERATORS (sizeof (operators) / sizeof (operators[0]))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Arguments::Arguments ()
|
||||
|
@ -268,6 +292,16 @@ void Arguments::categorize ()
|
|||
arg->second = "pattern";
|
||||
}
|
||||
|
||||
// <operator>
|
||||
else if (is_operator (arg->first))
|
||||
{
|
||||
found_non_sequence = true;
|
||||
if (found_sequence)
|
||||
found_something_after_sequence = true;
|
||||
|
||||
arg->second = "op";
|
||||
}
|
||||
|
||||
// If the type is not known, it is treated as a generic word.
|
||||
else
|
||||
{
|
||||
|
@ -698,6 +732,16 @@ bool Arguments::is_tag (const std::string& input)
|
|||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Arguments::is_operator (const std::string& input)
|
||||
{
|
||||
for (unsigned int i = 0; i < NUM_OPERATORS; ++i)
|
||||
if (operators[i] == input)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// ______________
|
||||
// | |
|
||||
|
@ -969,6 +1013,15 @@ bool Arguments::extract_tag (
|
|||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Arguments::extract_operator (
|
||||
const std::string& input,
|
||||
std::string& op)
|
||||
{
|
||||
op = input;
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Arguments Arguments::extract_read_only_filter ()
|
||||
{
|
||||
|
@ -993,6 +1046,7 @@ Arguments Arguments::extract_read_only_filter ()
|
|||
i->second == "attmod" ||
|
||||
i->second == "id" ||
|
||||
i->second == "uuid" ||
|
||||
i->second == "op" ||
|
||||
i->second == "word")
|
||||
{
|
||||
filter.push_back (*i);
|
||||
|
@ -1037,6 +1091,7 @@ Arguments Arguments::extract_write_filter ()
|
|||
i->second == "attmod" ||
|
||||
i->second == "id" ||
|
||||
i->second == "uuid" ||
|
||||
i->second == "op" ||
|
||||
i->second == "word")
|
||||
{
|
||||
filter.push_back (*i);
|
||||
|
@ -1083,6 +1138,7 @@ Arguments Arguments::extract_modifications ()
|
|||
else if (i->second == "tag" ||
|
||||
i->second == "attribute" ||
|
||||
i->second == "substitution" ||
|
||||
i->second == "op" ||
|
||||
i->second == "word")
|
||||
{
|
||||
modifications.push_back (*i);
|
||||
|
@ -1139,6 +1195,7 @@ void Arguments::dump (const std::string& label)
|
|||
color_map["id"] = Color ("yellow on gray3");
|
||||
color_map["uuid"] = Color ("yellow on gray3");
|
||||
color_map["substitution"] = Color ("bold cyan on gray3");
|
||||
color_map["op"] = Color ("bold blue on gray3");
|
||||
color_map["none"] = Color ("white on gray3");
|
||||
|
||||
Color color_debug (context.config.get ("color.debug"));
|
||||
|
@ -1172,7 +1229,6 @@ void Arguments::dump (const std::string& label)
|
|||
|
||||
out << view.render ();
|
||||
context.debug (out.str ());
|
||||
std::cout << out.str (); // TODO Remove
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -63,6 +63,7 @@ public:
|
|||
bool is_id (const std::string&);
|
||||
bool is_uuid (const std::string&);
|
||||
bool is_tag (const std::string&);
|
||||
bool is_operator (const std::string&);
|
||||
|
||||
// TODO Decide if these are really useful.
|
||||
bool extract_attr (const std::string&, std::string&, std::string&);
|
||||
|
@ -72,6 +73,7 @@ public:
|
|||
bool extract_id (const std::string&, std::vector <int>&);
|
||||
bool extract_uuid (const std::string&, std::vector <std::string>&);
|
||||
bool extract_tag (const std::string&, char&, std::string&);
|
||||
bool extract_operator (const std::string&, std::string&);
|
||||
|
||||
Arguments extract_read_only_filter ();
|
||||
Arguments extract_write_filter ();
|
||||
|
|
|
@ -170,8 +170,6 @@ int Context::run ()
|
|||
std::cout << colorizeDebug (*d) << "\n";
|
||||
else
|
||||
std::cout << *d << "\n";
|
||||
|
||||
args.dump ("Argument categorization");
|
||||
}
|
||||
|
||||
// Dump all headers, controlled by 'header' verbosity token.
|
||||
|
@ -222,6 +220,7 @@ int Context::dispatch (std::string &out)
|
|||
if (c->displays_id ())
|
||||
tdb.gc ();
|
||||
|
||||
args.dump ("Argument Categorization");
|
||||
return c->execute (out);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,15 +25,14 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <Context.h>
|
||||
#include <Expression.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Expression::Expression ()
|
||||
{
|
||||
}
|
||||
extern Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Expression::Expression (Arguments& arguments)
|
||||
: _original (arguments)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -49,13 +48,38 @@ bool Expression::eval (Task& task)
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Inserts the 'and' operator by default between terms that are not separated by
|
||||
// at least one operator.
|
||||
//
|
||||
// Converts: <term1> <term2> <op> <term3>
|
||||
// to: <term1> and <term2> <op> <term3>
|
||||
//
|
||||
void Expression::toInfix ()
|
||||
{
|
||||
_infix.clear ();
|
||||
|
||||
std::string previous = "op";
|
||||
std::vector <std::pair <std::string, std::string> >::iterator arg;
|
||||
for (arg = _original.begin (); arg != _original.end (); ++arg)
|
||||
{
|
||||
if (previous != "op" &&
|
||||
arg->second != "op")
|
||||
_infix.push_back (std::make_pair ("and", "op"));
|
||||
|
||||
_infix.push_back (*arg);
|
||||
previous = arg->second;
|
||||
}
|
||||
|
||||
_infix.dump ("Expression::toInfix");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Dijkstra Shunting Algorithm.
|
||||
void Expression::toPostfix ()
|
||||
{
|
||||
_postfix.clear ();
|
||||
|
||||
_postfix.dump ("Expression::toPostfix");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -35,16 +35,18 @@
|
|||
class Expression
|
||||
{
|
||||
public:
|
||||
Expression ();
|
||||
Expression (Arguments&);
|
||||
~Expression ();
|
||||
bool eval (Task&);
|
||||
void toInfix ();
|
||||
void toPostfix ();
|
||||
|
||||
void dump (const std::string&);
|
||||
|
||||
private:
|
||||
void toInfix ();
|
||||
void toPostfix ();
|
||||
Arguments _original;
|
||||
Arguments _infix;
|
||||
Arguments _postfix;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -95,6 +95,10 @@ int CmdCustom::execute (std::string& output)
|
|||
////////////////////////////////////
|
||||
Arguments f = context.args.extract_read_only_filter ();
|
||||
Expression e (f);
|
||||
e.toInfix ();
|
||||
e.toPostfix ();
|
||||
|
||||
return 0;
|
||||
// TODO e.apply (tasks);
|
||||
////////////////////////////////////
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue