Commit e7b56338 authored by Cocophotos's avatar Cocophotos

Merge branch 'release/1.0'

parents 6891a100 00fc2876
cmake_minimum_required (VERSION 2.8)
project (GRQL)
project (GRQL CXX)
option (WITH_TESTING OFF)
INCLUDE_DIRECTORIES(include lib)
add_subdirectory (include)
add_subdirectory (lib)
add_subdirectory (test)
include (CTest)
set(BOOST_TESTS
RuleParserSuite/SimpleRuleParserTest
GraphParserSuite/SimpleGraphParserTest
FeatureParserSuite/SimpleFeatureParserTest
FeatureParserSuite/AstFeatureParserTest
DFAParserSuite/DFAParserTest
DFAParserSuite/DFAASTTest
ConstraintParserSuite/ConstraintParserTest
CommandParserSuite/CommandParserTest
)
foreach(_test ${BOOST_TESTS})
add_test(
NAME
${_test}
COMMAND
Test --run_test=${_test}
)
endforeach()
if(WITH_TESTING)
if(WITH_TESTING STREQUAL "ON")
add_subdirectory (test)
include (CTest)
set(BOOST_TESTS
DFAParserSuite/DFAParserTest
DFAParserSuite/DFAASTTest
ConstraintParserSuite/ConstraintParserTest
RuleParserSuite/SimpleRuleParserTest
CommandParserSuite/CommandParserTest
CommandParserSuite/StatusEdgeCommandShouldHaveTwoArgs
FeatureParserSuite/SimpleFeatureParserTest
FeatureParserSuite/AstFeatureParserTest
)
foreach(_test ${BOOST_TESTS})
add_test(
NAME
${_test}
COMMAND
Test --run_test=${_test}
)
endforeach()
endif()
endif(WITH_TESTING)
......@@ -29,6 +29,13 @@ namespace grql { namespace ast
// (not really part of the AST.)
};
// aux['m'] OR test["value"]
// Allow the command to refer to a specific feature in a node or an edge
struct feature_dict_t{
std::string variable_;
std::string value_;
};
struct feature_value_t{
boost::optional<std::string> type_;
std::string value_;
......@@ -83,6 +90,12 @@ namespace grql { namespace ast
};
}}
BOOST_FUSION_ADAPT_STRUCT(
grql::ast::feature_dict_t,
(std::string, variable_)
(std::string, value_)
);
BOOST_FUSION_ADAPT_STRUCT(
grql::ast::feature_value_t,
(boost::optional<std::string>, type_)
......
......@@ -9,6 +9,8 @@ namespace grql { namespace ast
// The AST for a command
///////////////////////////////////////////////////////////////////////////
typedef boost::variant<feature_dict_t, std::vector<std::string> > command_value_t;
struct remove_command_t{
std::string command_;
std::string var_;
......@@ -26,21 +28,39 @@ namespace grql { namespace ast
std::string var_;
std::string varNewSrc_;
std::string varNewTar_;
boost::optional<feature_struct_t> features_;
};
struct feature_command_t{
std::string command_;
std::string var_;
std::string key_;
boost::optional<std::vector<feature_value_t> > values_;
boost::optional<command_value_t> values_;
};
struct modify_command_t{
std::string command_;
std::string var_;
std::string key1_;
std::string condition_;
std::string replace_;
};
struct status_edge_t{
std::string command_;
std::string var_;
bool surfacic_;
bool deep_;
};
typedef boost::variant<
remove_command_t,
add_edge_t,
move_edge_t,
feature_command_t
> command_t;
feature_command_t,
modify_command_t,
status_edge_t
> command_t;
}}
BOOST_FUSION_ADAPT_STRUCT(
......@@ -63,6 +83,7 @@ BOOST_FUSION_ADAPT_STRUCT(
(std::string, var_)
(std::string, varNewSrc_)
(std::string, varNewTar_)
(boost::optional<grql::ast::feature_struct_t>, features_)
);
BOOST_FUSION_ADAPT_STRUCT(
......@@ -70,7 +91,24 @@ BOOST_FUSION_ADAPT_STRUCT(
(std::string, command_)
(std::string, var_)
(std::string, key_)
(boost::optional<std::vector<grql::ast::feature_value_t> >, values_)
(boost::optional<grql::ast::command_value_t>, values_)
);
BOOST_FUSION_ADAPT_STRUCT(
grql::ast::modify_command_t,
(std::string, command_)
(std::string, var_)
(std::string, key1_)
(std::string, condition_)
(std::string, replace_)
);
BOOST_FUSION_ADAPT_STRUCT(
grql::ast::status_edge_t,
(std::string, command_)
(std::string, var_)
(bool, surfacic_)
(bool, deep_)
);
#endif // COMMAND_AST_HPP
......@@ -16,12 +16,6 @@ namespace grql { namespace ast
std::string var_target_;
};
struct edge_status_t
{
bool surfacic_;
bool deep_;
};
typedef boost::variant<
cvar_edge_t,
std::string
......@@ -31,7 +25,7 @@ namespace grql { namespace ast
std::string name_;
var_constraint_t var_;
std::vector<std::string> values_;
boost::optional<edge_status_t> status_;
boost::optional<std::string> status_;
};
struct feature_constraint_t{
......@@ -40,15 +34,16 @@ namespace grql { namespace ast
std::vector<std::string> labels_;
std::string surfacic_label_;
std::string deep_label_;
boost::optional<edge_status_t> status_;
};
boost::optional<std::string> status_;
};
struct move_constraint_t
{
std::string name_;
var_constraint_t var_;
std::vector<transition_t> dfa_;
boost::optional<edge_status_t> status_;
boost::optional<std::string> status_;
};
typedef boost::variant<
......@@ -64,18 +59,12 @@ BOOST_FUSION_ADAPT_STRUCT(
(std::string, var_target_)
);
BOOST_FUSION_ADAPT_STRUCT(
grql::ast::edge_status_t,
(bool, surfacic_)
(bool, deep_)
);
BOOST_FUSION_ADAPT_STRUCT(
grql::ast::simple_constraint_t,
(std::string, name_)
(grql::ast::var_constraint_t, var_)
(std::vector<std::string>, values_)
(boost::optional<grql::ast::edge_status_t>, status_)
(boost::optional<std::string>, status_)
);
BOOST_FUSION_ADAPT_STRUCT(
......@@ -85,7 +74,7 @@ BOOST_FUSION_ADAPT_STRUCT(
(std::vector<std::string>, labels_)
(std::string, surfacic_label_)
(std::string, deep_label_)
(boost::optional<grql::ast::edge_status_t>, status_)
(boost::optional<std::string>, status_)
);
BOOST_FUSION_ADAPT_STRUCT(
......@@ -93,7 +82,7 @@ BOOST_FUSION_ADAPT_STRUCT(
(std::string, name_)
(grql::ast::var_constraint_t, var_)
(std::vector<grql::ast::transition_t>, dfa_)
(boost::optional<grql::ast::edge_status_t>, status_)
(boost::optional<std::string>, status_)
);
......
......@@ -14,20 +14,16 @@ namespace grql { namespace ast
{
///////////////////////////////////////////////////////////////////////////
// The AST for a rule
///////////////////////////////////////////////////////////////////////////
struct precedence_relation_t{
node_t first;
node_t last;
};
///////////////////////////////////////////////////////////////////////////
typedef std::vector<precedence_relation_t> precedence_t;
typedef std::vector<std::string> precedence_t;
typedef std::vector<command_t> commands_t;
typedef std::vector<constraint_t> constraints_t;
struct subrule_t{
std::vector<graph_t> matchs_;
std::vector<graph_t> nacs_;
boost::optional<precedence_t> precedence_;
boost::optional<commands_t> commands_;
boost::optional<constraints_t> constraints_;
};
......@@ -38,16 +34,11 @@ namespace grql { namespace ast
};
}}
BOOST_FUSION_ADAPT_STRUCT(
grql::ast::precedence_relation_t,
(grql::ast::node_t, first_)
(grql::ast::node_t, last_)
);
BOOST_FUSION_ADAPT_STRUCT(
grql::ast::subrule_t,
(std::vector<grql::ast::graph_t>, matchs_)
//(grql::ast::precedence_t, precedence_)
(std::vector<grql::ast::graph_t>, nacs_)
(boost::optional<grql::ast::precedence_t>, precedence_)
(boost::optional<grql::ast::commands_t>, commands_)
(boost::optional<grql::ast::constraints_t>, constraints_)
);
......
......@@ -29,16 +29,16 @@ namespace grql
Iterator line_start = get_pos(err_pos, line);
if (err_pos != last)
{
std::cout << message << what << " line " << line << ':' << std::endl;
std::cout << get_line(line_start) << std::endl;
std::cerr << message << what << " line " << line << ':' << std::endl;
std::cerr << get_line(line_start) << std::endl;
for (; line_start != err_pos; ++line_start)
std::cout << ' ';
std::cout << '^' << std::endl;
std::cerr << ' ';
std::cerr << '^' << std::endl;
}
else
{
std::cout << "Unexpected end of file. ";
std::cout << message << what << " line " << line << std::endl;
std::cerr << "Unexpected end of file. ";
std::cerr << message << what << " line " << line << std::endl;
}
}
......
......@@ -3,10 +3,6 @@
#include "grql/error_handler.hpp"
#include "grql/parser/feature_parser.hpp"
#include "grql/parser/feature_parser_def.hpp"
#include "grql/parser/graph_parser.h"
#include "grql/parser/graph_parser_def.h"
#include "grql/parser/command_parser.h"
#include "grql/parser/command_parser_def.h"
#include "grql/parser/rule_parser.h"
#include "grql/parser/rule_parser_def.h"
......@@ -8,11 +8,15 @@
#include <boost/spirit/include/phoenix_operator.hpp>
#include <vector>
#include "grql/ast/command_ast.hpp"
#include "grql/error_handler.hpp"
#include "grql/skipper.h"
#include "grql/parser/feature_parser.hpp"
#include "grql/parser/string_parser.h"
#include "grql/parser/fdict_parser.h"
namespace grql { namespace parser
{
......@@ -21,25 +25,86 @@ namespace grql { namespace parser
namespace unicode = boost::spirit::unicode;
///////////////////////////////////////////////////////////////////////////////
// The graph grammar
// The command grammar
///////////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Skipper>
struct command_parser : qi::grammar<Iterator, ast::command_t(), Skipper>
{
command_parser(error_handler<Iterator>& error_handler);
command_parser(error_handler<Iterator>& error_handler)
: command_parser::base_type(command),
feature_structure(error_handler), sstring(error_handler),
fdict(error_handler)
{
qi::_3_type _3;
qi::_4_type _4;
using namespace qi;
using boost::phoenix::function;
typedef function<grql::error_handler<Iterator> > error_handler_function;
command = add_feature | modify_feature | remove_feature | append_feature
| add_edge | clone_edge | move_edge | remove_edge | remove_node | status;
status = ascii::string("edge_status") > '(' > variable > ',' > qi::bool_ > ',' > qi::bool_ > ')';
add_feature = ascii::string("add_feature") > '('
> variable > ',' > sstring > ',' > ( fdict | values )
> ')';
remove_feature = ascii::string("remove_feature") > '('
> variable > ',' > sstring
> ')';
modify_feature = ascii::string("modify_feature") > '(' > variable > ','
> variable > ':' > sstring //feat_value
> ',' > sstring > ')';
append_feature = ascii::string("append_feature") > '('
> variable > ',' > sstring > ',' > ( fdict | values )
> ')';
add_edge = ascii::string("add_edge") > '('
> variable > ',' > variable > ',' > feature_structure
> ')';
remove_edge = ascii::string("remove_edge") > '(' > variable > ')';
move_edge = ascii::string("move_edge") > '(' > variable > ',' > variable
> ',' > variable > -(',' > feature_structure) > ')';
clone_edge = ascii::string("clone_edge") > '(' > variable > ',' > variable
> ',' > variable > -(',' > feature_structure) > ')';
remove_node = ascii::string("remove_node") > '(' > variable > ')';
values = sstring % '|';
variable = lexeme[(alpha | qi::char_('_')) >> *(alnum | qi::char_('_'))];
///////////////////////////////////////////////////////////////////////
// Debugging and error handling and reporting support.
BOOST_SPIRIT_DEBUG_NODES(
(command) (variable) (values)
(add_feature) (modify_feature) (remove_feature) (append_feature)
(add_edge) (clone_edge) (move_edge) (remove_edge) (remove_node) (status)
);
///////////////////////////////////////////////////////////////////////
// Error handling: on error in feature, call error_handler.
on_error<fail>(command,
error_handler_function(error_handler)(
"Error! Expecting ", _4, _3));
}
fdict_parser<Iterator, Skipper> fdict;
feature_parser<Iterator, Skipper> feature_structure;
string_parser<Iterator, Skipper> sstring;
qi::rule<Iterator, ast::command_t(), Skipper> command;
qi::rule<Iterator, ast::feature_command_t(), Skipper> add_feature, modify_feature,
qi::rule<Iterator, ast::feature_command_t(), Skipper> add_feature,
append_feature, remove_feature;
qi::rule<Iterator, ast::modify_command_t(), Skipper> modify_feature;
qi::rule<Iterator, ast::remove_command_t(), Skipper> remove_node, remove_edge;
qi::rule<Iterator, ast::add_edge_t(), Skipper> add_edge;
qi::rule<Iterator, ast::move_edge_t(), Skipper> move_edge;
qi::rule<Iterator, ast::move_edge_t(), Skipper> move_edge, clone_edge;
qi::rule<Iterator, ast::status_edge_t(), Skipper> status;
qi::rule<Iterator, std::vector<ast::feature_value_t>(), Skipper> values;
qi::rule<Iterator, ast::feature_value_t(), Skipper> value;
qi::rule<Iterator, std::string(), Skipper> variable;
qi::rule<Iterator, std::vector<std::string>(), Skipper> values;
qi::rule<Iterator, std::string(), Skipper> variable;//, feat_value;
};
}}
......
#include "grql/parser/command_parser.h"
#include "grql/error_handler.hpp"
#include "grql/annotation.hpp"
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_lit.hpp>
namespace grql { namespace parser
{
template <typename Iterator, typename Skipper>
command_parser<Iterator, Skipper>::command_parser(error_handler<Iterator>& error_handler)
: command_parser::base_type(command), feature_structure(error_handler)
{
/*qi::_1_type _1;
qi::_2_type _2;*/
qi::_3_type _3;
qi::_4_type _4;
/*qi::_val_type _val;*/
qi::lexeme_type lexeme;
qi::alpha_type alpha;
qi::alnum_type alnum;
using ascii::string;
using qi::omit;
using qi::on_error;
using qi::on_success;
using qi::fail;
using boost::phoenix::function;
typedef function<grql::error_handler<Iterator> > error_handler_function;
//typedef function<grql::annotation<Iterator> > annotation_function;
command = add_feature | modify_feature | remove_feature | append_feature
| add_edge | move_edge | remove_edge | remove_node;
add_feature = ascii::string("add_feature") > '('
> variable > ',' > variable > ',' > values
> ')';
remove_feature = ascii::string("remove_feature") > '('
> variable > ',' > variable
> ')';
modify_feature = ascii::string("modify_feature") > '('
> variable > ',' > variable > ',' > values
> ')';
append_feature = ascii::string("append_feature") > '('
> variable > ',' > variable > ',' > values
> ')';
add_edge = ascii::string("add_edge") > '('
> variable > ',' > variable > ',' > feature_structure
> ')';
remove_edge = ascii::string("remove_edge") > '(' > variable > ')';
move_edge = ascii::string("move_edge") > '(' > variable > ',' > variable > ',' > variable > ')';
remove_node = ascii::string("remove_node") > '(' > variable > ')';
//TODO : split into values_parser
values = value % '|';
value = -ascii::string("r") > lexeme [ '"' >> *(qi::char_ - '"') >> '"' ];
variable = lexeme[(alpha | qi::char_('_')) >> *(alnum | qi::char_('_'))];
///////////////////////////////////////////////////////////////////////
// Debugging and error handling and reporting support.
BOOST_SPIRIT_DEBUG_NODES(
(command) (variable) (values) (value)
(add_feature) (modify_feature) (remove_feature) (append_feature)
(add_edge) (move_edge) (remove_edge) (remove_node)
);
///////////////////////////////////////////////////////////////////////
// Error handling: on error in feature, call error_handler.
on_error<fail>(command,
error_handler_function(error_handler)(
"Error! Expecting ", _4, _3));
///////////////////////////////////////////////////////////////////////
// Annotation: on success in feature, call annotation.
/*on_success(primary_expr,
annotation_function(error_handler.iters)(_val, _1));*/
}
}}
......@@ -8,12 +8,16 @@
#include <boost/spirit/include/phoenix_operator.hpp>
#include <vector>
#include "grql/ast/constraint_ast.h"
#include "grql/parser/dfa_parser_def.h"
#include "grql/parser/feature_parser.hpp"
#include "grql/error_handler.hpp"
#include "grql/skipper.h"
#include "grql/ast/constraint_ast.h"
#include "grql/parser/dfa_parser.h"
#include "grql/parser/string_parser.h"
#include "grql/parser/feature_parser.hpp"
namespace grql { namespace parser
{
namespace qi = boost::spirit::qi;
......@@ -26,18 +30,63 @@ namespace grql { namespace parser
template <typename Iterator, typename Skipper>
struct constraint_parser : qi::grammar<Iterator, ast::constraint_t(), Skipper>
{
constraint_parser(error_handler<Iterator>& error_handler);
constraint_parser(error_handler<Iterator>& error_handler)
: constraint_parser::base_type(constraint), dfa(error_handler), sstring(error_handler)
{
qi::_3_type _3;
qi::_4_type _4;
using namespace qi;
using boost::phoenix::function;
typedef function<grql::error_handler<Iterator> > error_handler_function;
//typedef function<grql::annotation<Iterator> > annotation_function;
constraint = redirect_down | share_down | share_up | add_feature | move_down | move_share_down;
move_share_down = ascii::string("move_share_down") > '(' > constraint_variable > ',' > dfa > -(',' > sstring ) > ')';
move_down = ascii::string("move_down") > '(' > constraint_variable > ',' > dfa > -(',' > sstring ) > ')';
add_feature = ascii::string("add_feature") > '(' > constraint_variable > ',' > values > ','
> sstring > ',' > sstring > -(',' > sstring) > ')';
share_down = ascii::string("share_down") > '(' > constraint_variable > ',' > values > -(',' > sstring ) > ')';
share_up = ascii::string("share_up") > '(' > constraint_variable > ',' > values > -(',' > sstring ) > ')';
redirect_down = ascii::string("redirect_down") > '(' > constraint_variable > ',' > values > -(',' > sstring) > ')';
constraint_variable = pair_variables | variable;
values = sstring % '|';
//value = lexeme [ '"' >> *(qi::char_ - '"') >> '"' ];
pair_variables = '(' > variable > ',' > variable > ')';
variable = lexeme[(alpha | qi::char_('_')) >> *(alnum | qi::char_('_'))];
///////////////////////////////////////////////////////////////////////
// Debugging and error handling and reporting support.
BOOST_SPIRIT_DEBUG_NODES(
(constraint)
(move_share_down) (move_down)
(add_feature) (share_down) (share_up) (redirect_down)
(dfa)
(constraint_variable)
(values) /*(value)*/ (pair_variables) (variable)
);
///////////////////////////////////////////////////////////////////////
// Error handling: on error in feature, call error_handler.
on_error<fail>(constraint,
error_handler_function(error_handler)(