logic: added query syntax and filtering system for search

This change allows the user to use a simple query syntax in the search field to filter the results using names,
operators and predefined filters.

The class QueryTree is capable of parsing a simple query language consiting of QueryNodes, subclassed as
QueryOperators, QueryCommands and QueryTokens. QueryToken identifies a Token by name. QueryCommand represents predefined
filters. QueryOperator defines the syntactic relationship.

QueryNode examples:
	"A" -> QueryToken that identifies the Token named A
	class -> QueryCommand that filters all Nodes that are classes
	. -> QueryOperator that concatenates filters

QueryExamples:
	"A".class -> All Tokens named A that are classes
	method.(private|protected) -> All methods that are private or protected
	"A".member -> All members of A
	"A":field.!const -> All fields of A that are not const (':' can be used instead of '.member')

QueryTree checks for correct operator precedence and validity of the query.
All QueryCommands can be found in data/query/QueryCommand.cpp
All QueryOperators can be found in data/query/QueryOperator.cpp

The parsed QueryTree is then passed to the class GraphFilterConductor, which is capable of applying the query on a
Graph. Each part of the query gets assigned a GraphFilter that filters the input Graph in order of node precedence. The
class SubGraph is used as intermediate container, only holding bare pointers to Nodes and Edges. The output Graph holds
all Nodes that match the query.

MessageActivateTokens is used to show all of the results in the CodeView. The GraphView currently only shows the first
Node of the results.

bug id = #6
This commit is contained in:
Eberhard Graether
2014-08-30 18:24:00 +02:00
parent b0d27ba559
commit c84972b96e
41 changed files with 1917 additions and 80 deletions
@@ -20,4 +20,4 @@ public:
const Id tokenId;
};
#endif // MESSAGE_ACTIVATE_TOKEN_LOCATION_H
#endif // MESSAGE_ACTIVATE_TOKEN_H
@@ -0,0 +1,23 @@
#ifndef MESSAGE_ACTIVATE_TOKENS_H
#define MESSAGE_ACTIVATE_TOKENS_H
#include "utility/messaging/Message.h"
#include "utility/types.h"
class MessageActivateTokens: public Message<MessageActivateTokens>
{
public:
MessageActivateTokens(const std::vector<Id>& tokenIds)
: tokenIds(tokenIds)
{
}
static const std::string getStaticType()
{
return "MessageActivateTokens";
}
const std::vector<Id> tokenIds;
};
#endif // MESSAGE_ACTIVATE_TOKENS_H
+66
View File
@@ -12,6 +12,18 @@ namespace utility
template<typename ContainerType>
ContainerType split(const std::string& str, const std::string& delimiter);
template<typename ContainerType>
ContainerType tokenize(const std::string& str, char delimiter);
template<typename ContainerType>
ContainerType tokenize(const std::string& str, const std::string& delimiter);
template<typename ContainerType>
ContainerType tokenize(const ContainerType& list, char delimiter);
template<typename ContainerType>
ContainerType tokenize(const ContainerType& list, const std::string& delimiter);
std::string substrAfter(const std::string& str, char delimiter);
bool isPrefix(const std::string& prefix, const std::string& text);
@@ -41,4 +53,58 @@ ContainerType utility::split(const std::string& str, const std::string& delimite
return c;
}
template<typename ContainerType>
ContainerType utility::tokenize(const std::string& str, char delimiter)
{
return tokenize<ContainerType>(str, std::string(1, delimiter));
}
template<typename ContainerType>
ContainerType utility::tokenize(const std::string& str, const std::string& delimiter)
{
size_t pos = 0;
size_t oldPos = 0;
ContainerType c;
do
{
pos = str.find(delimiter, oldPos);
if (pos != oldPos)
{
c.push_back(str.substr(oldPos, pos - oldPos));
}
if (pos != std::string::npos)
{
c.push_back(str.substr(pos, delimiter.size()));
}
oldPos = pos + delimiter.size();
}
while (pos != std::string::npos && oldPos < str.size());
return c;
}
template<typename ContainerType>
ContainerType utility::tokenize(const ContainerType& list, char delimiter)
{
return tokenize<ContainerType>(list, std::string(1, delimiter));
}
template<typename ContainerType>
ContainerType utility::tokenize(const ContainerType& list, const std::string& delimiter)
{
ContainerType c;
for (std::string str : list)
{
ContainerType c2 = tokenize<ContainerType>(str, delimiter);
c.insert(c.end(), c2.begin(), c2.end());
}
return c;
}
#endif // UTILITY_STRING_H