diff --git a/cypher/codegen/cppgen.hpp b/cypher/codegen/cppgen.hpp index 0d051ddbf..e21626153 100644 --- a/cypher/codegen/cppgen.hpp +++ b/cypher/codegen/cppgen.hpp @@ -3,13 +3,25 @@ #include "cypher/visitor/traverser.hpp" +#include +using std::cout; +using std::endl; + class CppGen : public Traverser { struct CreateGen : public Traverser { void visit(ast::Pattern& pattern) override { - + Traverser::visit(pattern); + } + + void visit(ast::Node& node) override + { + auto next_node = node.props->next; + cout << next_node->value->idn->name; + + Traverser::visit(node); } }; @@ -17,10 +29,10 @@ public: void visit(ast::Start& start) override { - + Traverser::visit(start); } - void visit(ast::Create create) override + void visit(ast::Create& create) override { auto create_gen = CreateGen(); create.accept(create_gen); diff --git a/cypher/compiler.hpp b/cypher/compiler.hpp index 7d48053f5..400cc9b8c 100644 --- a/cypher/compiler.hpp +++ b/cypher/compiler.hpp @@ -4,8 +4,6 @@ #include "cypher_lexer.hpp" #include "parser.hpp" -#include "debug/tree_print.hpp" - namespace cypher { @@ -14,14 +12,12 @@ class Compiler public: Compiler() = default; - void compile(const std::string& input) + ast::Ast syntax_tree(const std::string& input) { auto parser = cypher::Parser(); auto tokenizer = lexer.tokenize(input); auto tree = parser.parse(tokenizer); - - PrintVisitor printer(std::cout); - tree.root->accept(printer); + return std::move(tree); } private: diff --git a/cypher/cypher.y b/cypher/cypher.y index f66ee1ff2..b8e1ff202 100644 --- a/cypher/cypher.y +++ b/cypher/cypher.y @@ -97,7 +97,7 @@ pattern(P) ::= node(N). { %type rel {ast::Relationship*} -rel(R) ::= MINUS rel_spec(S) MINUS. { // unidirectional +rel(R) ::= MINUS rel_spec(S) MINUS. { // bidirectional R = ast->create(S, ast::Relationship::Both); } diff --git a/cypher/debug/tree_print.hpp b/cypher/debug/tree_print.hpp index 4a095aa8a..6041edd3e 100644 --- a/cypher/debug/tree_print.hpp +++ b/cypher/debug/tree_print.hpp @@ -15,7 +15,7 @@ public: Printer(std::ostream& stream, const std::string& header) : stream(stream) { - stream << header; + // stream << header; } ~Printer() diff --git a/cypher/parser.cpp b/cypher/parser.cpp index e0a1192c9..0405a0751 100644 --- a/cypher/parser.cpp +++ b/cypher/parser.cpp @@ -3,52 +3,62 @@ #include #include "compiler.hpp" +#include "debug/tree_print.hpp" +#include "codegen/cppgen.hpp" -int main() +using std::cout; +using std::endl; +using vector_str = std::vector; + +// TODO: extract from here +// TODO: write more safe and optimal +vector_str all_arguments(int argc, char *argv[]) { + vector_str args(argv + 1, argv + argc); + return args; +} + +std::string get_argument(const vector_str& all, + const std::string& flag, + const std::string& default_value) +{ + auto it = std::find(all.begin(), all.end(), flag); + if (it == all.end()) { + return default_value; + } + auto pos = std::distance(all.begin(), it); + return all[pos + 1]; +} + +// * QUERY EXAMPLES * +// "CREATE (n { name: 'Dominik', age: 24, role: 'CEO' }) return n" +// "MATCH (user:User { name: 'Dominik', age: 8 + 4})-[has:HAS|IS|CAN { duration: 'PERMANENT'}]->(item:Item)--(shop)" +// "MATCH (user:User { name: 'Dominik', age: 24})-[has:HAS]->(item:Item) WHERE item.name = 'XPS 13' AND item.price = 11999.99 RETURN user, has, item" + +// * INPUT ARGUMENTS * +// -q -> query +// -v -> visitor + +int main(int argc, char *argv[]) +{ + // arguments parsing + auto arguments = all_arguments(argc, argv); + auto cypher_query = get_argument(arguments, "-q", "CREATE (n {name: 'Domko', age: 24}) return n"); + auto traverser = get_argument(arguments, "-t", "print"); + + // traversers + auto print_traverser = Traverser::sptr(new PrintVisitor(cout)); + auto cppgen_traverser = Traverser::sptr(new CppGen()); + std::map traversers = { + {"print", print_traverser}, + {"code", cppgen_traverser} + }; + cypher::Compiler compiler; + auto tree = compiler.syntax_tree(cypher_query); - //std::string input("MATCH (user:User { name: 'Dominik', age: 24})-[has:HAS]->(item:Item) WHERE item.name = 'XPS 13' AND item.price = 11999.99 RETURN user, has, item"); - - std::string input("create (n { name: 'Dominik', age: 24 }) return n"); - - compiler.compile(input); - - /* void* parser = cy */ - /* CypherLexer lexer; */ - - /* //std::string input("matcH (user:User { name: 'Dominik', age: 8 + 4})-[has:HAS|IS|CAN { duration: 'PERMANENT'}]->(item:Item)--(shop)"); */ - - /* std::string input("MATCH (user:User { name: 'Dominik', age: 24})-[has:HAS]->(item:Item) WHERE item.name = 'XPS 13' AND item.price = 11999.99 RETURN user, has, item"); */ - - /* auto tokenizer = lexer.tokenize(input); */ - - /* std::vector v; */ - - /* while(true) */ - /* { */ - /* v.push_back(tokenizer.lookup()); */ - /* auto token = v.back(); */ - - /* //std::cout << token->id << " -> " << token->value << std::endl; */ - - /* auto ast = new ast::Ast(); */ - - /* try */ - /* { */ - /* cypher_parser(parser, token.id, &token, ast); */ - /* } */ - /* catch(...) */ - /* { */ - /* std::cout << "caught exception." << std::endl; */ - /* exit(0); */ - /* } */ - - /* if(token.id == 0) */ - /* break; */ - /* } */ - - /* cypher_parserFree(parser, free); */ + auto t = traversers[traverser]; + tree.root->accept(*t); return 0; } diff --git a/cypher/parser.hpp b/cypher/parser.hpp index 36d016b8c..eed6d9123 100644 --- a/cypher/parser.hpp +++ b/cypher/parser.hpp @@ -36,7 +36,7 @@ public: { tokens.emplace_back(tokenizer.lookup()); auto& token = tokens.back(); - std::cout << token << std::endl; + // std::cout << token << std::endl; cypher_parser(parser, token.id, &token, &tree); } while(tokens.back().id != 0); diff --git a/cypher/proba.cpp b/cypher/proba.cpp deleted file mode 100644 index 4256b73e3..000000000 --- a/cypher/proba.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include - -#include "ast/float.hpp" - -int main(void) -{ - auto f = new Float(3); - - return 0; -} diff --git a/cypher/visitor/traverser.hpp b/cypher/visitor/traverser.hpp index 9d080f5ef..08f6c249f 100644 --- a/cypher/visitor/traverser.hpp +++ b/cypher/visitor/traverser.hpp @@ -8,6 +8,9 @@ class Traverser : public ast::AstVisitor { public: + using uptr = std::unique_ptr; + using sptr = std::shared_ptr; + void visit(ast::Start& start) override { accept(start.read_query);