diff --git a/langkit/langkit_parser.cpp b/langkit/langkit_parser.cpp index 6520506..adbe9d7 100644 --- a/langkit/langkit_parser.cpp +++ b/langkit/langkit_parser.cpp @@ -55,8 +55,12 @@ std::pair Or_Rule(Token_Iterator iter, Token_Iterator end, if (new_id != -1) { parent->filename = (*iter)->filename; parent->start = (*iter)->start; - parent->end = (*(result.first - 1))->end; - + if (result.first == iter) { + parent->end = (*iter)->start; + } + else { + parent->end = (*(result.first - 1))->end; + } prev_parent->children.push_back(parent); } return std::pair(result.first, true); @@ -73,8 +77,12 @@ std::pair Or_Rule(Token_Iterator iter, Token_Iterator end, parent->filename = (*iter)->filename; parent->start = (*iter)->start; - parent->end = (*(result.first - 1))->end; - + if (result.first == iter) { + parent->end = (*iter)->start; + } + else { + parent->end = (*(result.first - 1))->end; + } prev_parent->children.push_back(parent); } @@ -112,8 +120,12 @@ std::pair And_Rule(Token_Iterator iter, Token_Iterator end parent->filename = (*iter)->filename; parent->start = (*iter)->start; - parent->end = (*(result.first - 1))->end; - + if (result.first == iter) { + parent->end = (*iter)->start; + } + else { + parent->end = (*(result.first - 1))->end; + } prev_parent->children.push_back(parent); } @@ -152,7 +164,12 @@ std::pair Kleene_Rule parent->filename = (*iter)->filename; parent->start = (*iter)->start; - parent->end = (*(result.first - 1))->end; + if (result.first == iter) { + parent->end = (*iter)->start; + } + else { + parent->end = (*(result.first - 1))->end; + } prev_parent->children.push_back(parent); } @@ -192,8 +209,12 @@ std::pair Plus_Rule parent->filename = (*iter)->filename; parent->start = (*iter)->start; - parent->end = (*(result.first - 1))->end; - + if (result.first == iter) { + parent->end = (*iter)->start; + } + else { + parent->end = (*(result.first - 1))->end; + } prev_parent->children.push_back(parent); } @@ -232,8 +253,12 @@ std::pair Optional_Rule parent->filename = (*iter)->filename; parent->start = (*iter)->start; - parent->end = (*(result.first - 1))->end; - + if (result.first == iter) { + parent->end = (*iter)->start; + } + else { + parent->end = (*(result.first - 1))->end; + } prev_parent->children.push_back(parent); } @@ -244,7 +269,7 @@ std::pair Optional_Rule } } -std::pair Nop_Rule +std::pair Epsilon_Rule (Token_Iterator iter, Token_Iterator end, TokenPtr parent, bool keep, int new_id, Rule rule) { TokenPtr prev_parent = parent; @@ -255,8 +280,7 @@ std::pair Nop_Rule } std::pair result; - result.second = true; - if ((new_iter != end) && (result.second == true)) { + if ((new_iter != end)) { result = rule(new_iter, end, parent); new_iter = result.first; } @@ -264,12 +288,49 @@ std::pair Nop_Rule if (new_id != -1) { parent->filename = (*iter)->filename; parent->start = (*iter)->start; - parent->end = (*(result.first - 1))->end; + if (result.first == iter) { + parent->end = (*iter)->start; + } + else { + parent->end = (*(result.first - 1))->end; + } prev_parent->children.push_back(parent); } - return std::pair(iter, true); + return std::pair(iter, result.second); +} + +std::pair Wrap_Rule + (Token_Iterator iter, Token_Iterator end, TokenPtr parent, bool keep, int new_id, Rule rule) { + + TokenPtr prev_parent = parent; + Token_Iterator new_iter = iter; + + if (new_id != -1) { + parent = TokenPtr(new Token("", new_id, parent->filename)); + } + + std::pair result; + if ((new_iter != end)) { + result = rule(new_iter, end, parent); + new_iter = result.first; + } + + if (new_id != -1) { + parent->filename = (*iter)->filename; + parent->start = (*iter)->start; + if (result.first == iter) { + parent->end = (*iter)->start; + } + else { + parent->end = (*(result.first - 1))->end; + } + + prev_parent->children.push_back(parent); + } + + return std::pair(result.first, result.second); } Rule Str(const std::string &text, bool keep) { @@ -294,6 +355,10 @@ Rule Ign(Rule rule) { return rule; } -Rule Nop(Rule rule) { - return Rule(boost::bind(Nop_Rule, _1, _2, _3, _4, _5, rule)); +Rule Epsilon(Rule rule) { + return Rule(boost::bind(Epsilon_Rule, _1, _2, _3, _4, _5, rule)); +} + +Rule Wrap(Rule rule) { + return Rule(boost::bind(Wrap_Rule, _1, _2, _3, _4, _5, rule)); } diff --git a/langkit/langkit_parser.hpp b/langkit/langkit_parser.hpp index 6acdcf8..97ee6c5 100644 --- a/langkit/langkit_parser.hpp +++ b/langkit/langkit_parser.hpp @@ -50,7 +50,10 @@ std::pair Plus_Rule std::pair Optional_Rule (Token_Iterator iter, Token_Iterator end, TokenPtr parent, bool keep, int new_id, struct Rule rule); -std::pair Nop_Rule +std::pair Epsilon_Rule + (Token_Iterator iter, Token_Iterator end, TokenPtr parent, bool keep, int new_id, struct Rule rule); + +std::pair Wrap_Rule (Token_Iterator iter, Token_Iterator end, TokenPtr parent, bool keep, int new_id, struct Rule rule); struct Rule { @@ -102,6 +105,7 @@ Rule Str(const std::string &text); Rule Id(int id); Rule Ign(Rule rule); -Rule Nop(Rule rule); +Rule Epsilon(Rule rule); +Rule Wrap(Rule rule); #endif /* LANGKIT_PARSER_HPP_ */ diff --git a/langkit/main.cpp b/langkit/main.cpp index 25253da..e98b294 100644 --- a/langkit/main.cpp +++ b/langkit/main.cpp @@ -96,7 +96,7 @@ void parse(std::vector &tokens, const char *filename) { return_statement = Ign(Str("return")) >> expression; */ Rule rule(TokenType::Equation); - rule = Str("break"); + rule = Wrap(Str("break")); std::cout << "Check: " << rule.impl->new_id << std::endl; diff --git a/wesley/main.cpp b/wesley/main.cpp index f6bab7c..a41cf20 100644 --- a/wesley/main.cpp +++ b/wesley/main.cpp @@ -226,13 +226,13 @@ Rule build_parser_rules() { negate = Ign(Str("-")) >> boolean; prefix = (Str("++") >> (boolean | arraycall)) | (Str("--") >> (boolean | arraycall)); arraycall = value >> +((Ign(Id(TokenType::Square_Open)) >> boolean >> Ign(Id(TokenType::Square_Close)))); - value = vardecl | arrayinit | block | (Ign(Id(TokenType::Parens_Open)) >> boolean >> Ign(Id(TokenType::Parens_Close))) | return_statement | + value = vardecl | arrayinit | block | (Ign(Id(TokenType::Parens_Open)) >> boolean >> Ign(Id(TokenType::Parens_Close))) | return_statement | break_statement | funcall | Id(TokenType::Identifier) | Id(TokenType::Real_Number) | Id(TokenType::Integer) | Id(TokenType::Quoted_String) | Id(TokenType::Single_Quoted_String) ; arrayinit = Ign(Id(TokenType::Square_Open)) >> ~(boolean >> *(Ign(Str(",")) >> boolean)) >> Ign(Id(TokenType::Square_Close)); vardecl = Ign(Str("var")) >> Id(TokenType::Identifier); return_statement = Ign(Str("return")) >> ~boolean; - //break_statement = Ign(Str("break")) >> ~Ign(Id(TokenType::Semicolon)); + break_statement = Wrap(Ign(Str("break"))); return rule; } @@ -287,10 +287,6 @@ Boxed_Value eval_token(BoxedCPP_System &ss, TokenPtr node) { else if (node->text == "false") { retval = Boxed_Value(false); } - else if (node->text == "break") { - //todo: this is a WORKAROUND for parser combinator limitations - throw BreakLoop(node); - } else { try { retval = ss.get_object(node->text);