diff --git a/langkit/langkit_parser.cpp b/langkit/langkit_parser.cpp index 16bd635..9f9a8f9 100644 --- a/langkit/langkit_parser.cpp +++ b/langkit/langkit_parser.cpp @@ -1,6 +1,7 @@ // This file is distributed under the BSD License. // See LICENSE.TXT for details. +#include #include #include "langkit_lexer.hpp" @@ -32,39 +33,52 @@ std::pair Type_Rule(Token_Iterator iter, Token_Iterator en return std::pair(iter, false); } -std::pair Or_Rule(Token_Iterator iter, Token_Iterator end, TokenPtr parent, const Rule &lhs, const Rule &rhs, bool keep, int new_id) { +std::pair Or_Rule(Token_Iterator iter, Token_Iterator end, TokenPtr parent, const RulePtr lhs, const RulePtr rhs, bool keep) { Token_Iterator new_iter; + unsigned int prev_size = parent->children.size(); if (*iter != *end) { - new_iter = lhs.rule(iter, end, parent).first; + std::pair result = lhs->rule(iter, end, parent); - if (new_iter != iter) { - return std::pair(new_iter, true); + if (result.second) { + return std::pair(result.first, true); } else { - new_iter = rhs.rule(iter, end, parent).first; - if (new_iter != iter) { - return std::pair(new_iter, true); + result = rhs->rule(iter, end, parent); + if (result.second) { + return std::pair(result.first, true); } } } + + if (parent->children.size() != prev_size) { + //Clear out the partial matches + parent->children.erase(parent->children.begin() + prev_size, parent->children.end()); + } + return std::pair(iter, false); } -std::pair And_Rule(Token_Iterator iter, Token_Iterator end, TokenPtr parent, const Rule &lhs, const Rule &rhs, bool keep, int new_id) { +std::pair And_Rule(Token_Iterator iter, Token_Iterator end, TokenPtr parent, const RulePtr lhs, const RulePtr rhs, bool keep) { Token_Iterator lhs_iter, rhs_iter; + unsigned int prev_size = parent->children.size(); if (*iter != *end) { - lhs_iter = lhs.rule(iter, end, parent).first; + std::pair result = lhs->rule(iter, end, parent); - if (lhs_iter != iter) { - rhs_iter = rhs.rule(iter, end, parent).first; - if (rhs_iter != iter) { - return std::pair(rhs_iter, true); + if (result.second) { + result = rhs->rule(result.first, end, parent); + if (result.second) { + return std::pair(result.first, true); } } } + if (parent->children.size() != prev_size) { + //Clear out the partial matches + parent->children.erase(parent->children.begin() + prev_size, parent->children.end()); + } + return std::pair(iter, false); } diff --git a/langkit/langkit_parser.hpp b/langkit/langkit_parser.hpp index 03f4bb4..f2b72b7 100644 --- a/langkit/langkit_parser.hpp +++ b/langkit/langkit_parser.hpp @@ -9,14 +9,17 @@ #include "langkit_lexer.hpp" typedef std::vector::iterator Token_Iterator; +typedef std::tr1::shared_ptr RulePtr; +typedef boost::function(Token_Iterator iter, Token_Iterator end, TokenPtr parent)> RuleFun; struct Rule { int identifier; - boost::function(Token_Iterator iter, Token_Iterator end, TokenPtr parent)> rule; + RuleFun rule; std::pair operator()(Token_Iterator iter, Token_Iterator end, TokenPtr parent); Rule() : identifier(-1) {} Rule(int id) : identifier(id) {} + Rule(RuleFun fun) : rule(fun) {} }; std::pair String_Rule @@ -26,10 +29,10 @@ std::pair Type_Rule (Token_Iterator iter, Token_Iterator end, TokenPtr parent, const int val, bool keep); std::pair Or_Rule - (Token_Iterator iter, Token_Iterator end, TokenPtr parent, const Rule &lhs, const Rule &rhs, bool keep, int new_id); + (Token_Iterator iter, Token_Iterator end, TokenPtr parent, const RulePtr lhs, const RulePtr rhs, bool keep); std::pair And_Rule - (Token_Iterator iter, Token_Iterator end, TokenPtr parent, const Rule &lhs, const Rule &rhs, bool keep, int new_id); + (Token_Iterator iter, Token_Iterator end, TokenPtr parent, const RulePtr lhs, const RulePtr rhs, bool keep); #endif /* LANGKIT_PARSER_HPP_ */ diff --git a/langkit/main.cpp b/langkit/main.cpp index ffa5ca1..d90bfce 100644 --- a/langkit/main.cpp +++ b/langkit/main.cpp @@ -48,6 +48,7 @@ std::string load_file(const char *filename) { } void parse(std::vector &tokens) { + /* Rule rule; rule.rule = boost::bind(String_Rule, _1, _2, _3, "def", true); @@ -60,6 +61,22 @@ void parse(std::vector &tokens) { std::cout << "Parse successful: " << std::endl; debug_print(parent, ""); } + */ + RulePtr lhs (new Rule()); + RulePtr rhs (new Rule()); + RulePtr rule (new Rule(boost::bind(Or_Rule, _1, _2, _3, lhs, rhs, true))); + lhs->rule = boost::bind(String_Rule, _1, _2, _3, "def", true); + rhs->rule = boost::bind(String_Rule, _1, _2, _3, "int", true); + + Token_Iterator iter = tokens.begin(), end = tokens.end(); + TokenPtr parent(new Token("Root", 0, "test")); + + std::pair results = (*rule)(iter, end, parent); + + if (results.second) { + std::cout << "Parse successful: " << std::endl; + debug_print(parent, ""); + } }