diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7079b7f1e..a16bacf69 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,11 +23,9 @@ set (task_SRCS A3.cpp A3.h ISO8601.cpp ISO8601.h JSON.cpp JSON.h Lexer.cpp Lexer.h - LRParser.cpp LRParser.h Msg.cpp Msg.h Nibbler.cpp Nibbler.h OldDuration.cpp OldDuration.h - Parser.cpp Parser.h Path.cpp Path.h RX.cpp RX.h Socket.cpp Socket.h @@ -61,13 +59,11 @@ set (task_SRCS A3.cpp A3.h add_library (task STATIC ${task_SRCS}) add_executable (task_executable main.cpp) add_executable (calc_executable calc.cpp) -add_executable (parser_executable bnf.cpp) add_executable (args_executable args.cpp) # Yes, 'task' is included twice, otherwise linking fails on assorted OSes. target_link_libraries (task_executable task commands columns task ${TASK_LIBRARIES}) target_link_libraries (calc_executable task commands columns task ${TASK_LIBRARIES}) -target_link_libraries (parser_executable task commands columns task ${TASK_LIBRARIES}) target_link_libraries (args_executable task commands columns task ${TASK_LIBRARIES}) set_property (TARGET task_executable PROPERTY OUTPUT_NAME "task") @@ -75,7 +71,6 @@ set_property (TARGET task_executable PROPERTY OUTPUT_NAME "task") install (TARGETS task_executable DESTINATION ${TASK_BINDIR}) set_property (TARGET calc_executable PROPERTY OUTPUT_NAME "calc") -set_property (TARGET parser_executable PROPERTY OUTPUT_NAME "parser") set_property (TARGET args_executable PROPERTY OUTPUT_NAME "args") #SET(CMAKE_BUILD_TYPE gcov) diff --git a/src/LRParser.cpp b/src/LRParser.cpp deleted file mode 100644 index b068a655b..000000000 --- a/src/LRParser.cpp +++ /dev/null @@ -1,471 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// taskwarrior - a command line task list manager. -// -// Copyright 2006-2013, Paul Beckingham, Federico Hernandez. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// http://www.opensource.org/licenses/mit-license.php -// -//////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include -#include -#include - -//////////////////////////////////////////////////////////////////////////////// -LRParser::LRParser () -{ -} - -//////////////////////////////////////////////////////////////////////////////// -// This is called only from external code. -Tree* LRParser::parse (const std::string& tokens) -{ - Tree* tree = new Tree ("root"); - if (! tree) - throw std::string ("Failed to allocate memory for parse tree."); - - unsigned int cursor = 0; - if (matchRule (_primary, '=', cursor, tokens, tree)) - { - if (_verbose) - std::cout << "syntax pass" << std::endl; - } - else - { - if (_verbose) - std::cout << "syntax fail" << std::endl; - - delete tree; - tree = NULL; - } - - return tree; -} - -//////////////////////////////////////////////////////////////////////////////// -void LRParser::addEntity (const std::string& name, const std::string& value) -{ - _entities.insert (std::pair (name, value)); -} - -//////////////////////////////////////////////////////////////////////////////// -// Wraps calls to matchRule, while properly handling the quantifier. -bool LRParser::matchRuleQuant ( - const std::string& rule, - char quantifier, - unsigned int& cursor, - const std::string& tokens, - Tree* tree) -{ - // Must match exactly once, so run once and return the result. - if (quantifier == '=') - { - return matchRule (rule, quantifier, cursor, tokens, tree); - } - - // May match zero or one time. If it matches, the cursor will be advanced. - // If it fails, the cursor will not be advanced, but this is still considered - // successful. Return true either way, but backtrack the cursor on failure. - - // TODO Make greedy. - else if (quantifier == '?') - { - unsigned int original_cursor = cursor; - if (! matchRule (rule, quantifier, cursor, tokens, tree)) - cursor = original_cursor; - return true; - } - - // May match 1 or more times. If it matches on the first attempt, continue - // to greedily match until it fails. If it fails on the first attempt, then - // the rule fails. - - // TODO Make greedy. - else if (quantifier == '+') - { - if (! matchRule (rule, quantifier, cursor, tokens, tree)) - return false; - - while (matchRule (rule, quantifier, cursor, tokens, tree)) - ; - return true; - } - - // May match zero or more times. Keep calling while there are matches, and - // return true always. Backtrack the cursor on failure. - - // TODO Make greedy. - else if (quantifier == '*') - { - bool result; - do - { - unsigned int original_cursor = cursor; - result = matchRule (rule, quantifier, cursor, tokens, tree); - if (! result) - cursor = original_cursor; - } - while (result); - return true; - } - - throw std::string ("LRParser::matchRuleQuant - this should never happen."); - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// Returns true, with cursor incremented, if any of the alternates match. -bool LRParser::matchRule ( - const std::string& rule, - char quantifier, - unsigned int& cursor, - const std::string& tokens, - Tree* tree) -{ - if (cursor >= tokens.length ()) return false; - unsigned int original_cursor = cursor; // Preserve - - for (unsigned int alt = 0; - alt < _rules[rule].size () && cursor < tokens.length (); - ++alt) - { - Tree* b = new Tree (rule); - if (! b) - throw std::string ("Failed to allocate memory for parse tree."); - - if (matchAlternate (rule, quantifier, alt, _rules[rule][alt], cursor, tokens, b)) - { - if (_verbose) - std::cout << "\033[32m" - << "matchRule " - << rule - << quantifier - << "/a" - << alt - << " tokens[" - << cursor - 1 - << "]=" - << visible (tokens[cursor - 1]) - << " SUCCEED" - << " " - << tree - << "->" - << b - << "\033[0m" - << std::endl; - - tree->addBranch (b); - return true; - } - - delete b; - } - - cursor = original_cursor; // Restore - - if (_verbose) - std::cout << "\033[31m" - << "matchRule " - << rule - << quantifier - << " FAIL" - << "\033[0m" - << std::endl; - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// Returns true, with cursor incremented, if all of the token match. -bool LRParser::matchAlternate ( - const std::string& rule, - char quantifier, - unsigned int alt, - const Alternate& alternate, - unsigned int& cursor, - const std::string& tokens, - Tree* tree) -{ - if (cursor >= tokens.length ()) return false; - - unsigned int original_cursor = cursor; // Preserve - - for (unsigned int token = 0; - token < alternate.size () && cursor < tokens.length (); - ++token) - { - if (! matchToken (rule, quantifier, alt, token, alternate[token], cursor, tokens, tree)) - { - cursor = original_cursor; // Restore - if (_verbose) - std::cout << "\033[31m" - << "matchAlternate " - << rule - << quantifier - << "/a" - << alt - << "/t" - << token - << " tokens[" - << cursor - << "]=" - << visible (tokens[cursor]) - << " FAIL" - << "\033[0m" - << std::endl; - - return false; - } - - if (_verbose) - std::cout << "\033[32m" - << "matchAlternate " - << rule - << quantifier - << "/a" - << alt - << "/t" - << token - << " SUCCEED" - << "\033[0m" - << std::endl; - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// Returns true, if the token, an optional quantifier, and all optional -// modifiers match. -bool LRParser::matchToken ( - const std::string& rule, - char quantifier, - unsigned int alt, - unsigned int tok, - const Token& token, - unsigned int& cursor, - const std::string& tokens, - Tree* tree) -{ - if (cursor >= tokens.length ()) return false; - - unsigned int original_cursor = cursor; // Preserve - - if (tokenMatchRule (rule, quantifier, alt, tok, token, cursor, tokens, tree) || - tokenMatchSpecialLiteral (token, cursor, tokens, tree) || - tokenMatchLiteral (token, cursor, tokens, tree) || - tokenMatchRegex (token, cursor, tokens, tree)) - { - if (_verbose) - std::cout << "\033[32m" - << "matchToken " - << rule - << quantifier - << "/a" - << alt - << "/t" - << tok - << " tokens[" - << cursor - << "]=" - << visible (tokens[cursor]) - << " token=" - << token.value - << " SUCCEED" - << "\033[0m" - << std::endl; - - return true; - } - - cursor = original_cursor; // Restore - - if (_verbose) - std::cout << "\033[31m" - << "matchToken " - << rule - << quantifier - << "/a" - << alt - << "/t" - << tok - << " tokens[" - << cursor - << "]=" - << visible (tokens[cursor]) - << " token=" - << token.value - << " FAIL" - << "\033[0m" - << std::endl; - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool LRParser::tokenMatchSpecialLiteral ( - const Token& token, - unsigned int& cursor, - const std::string& tokens, - Tree* tree) -{ - if (cursor >= tokens.length ()) return false; - - if ((tokens[cursor] == '\t' && token.value == "\"\\t\"") || - (tokens[cursor] == '\n' && token.value == "\"\\n\"") || - (tokens[cursor] == '\r' && token.value == "\"\\r\"") || - (tokens[cursor] == '\f' && token.value == "\"\\f\"") || - (tokens[cursor] == '\v' && token.value == "\"\\v\"") || - (tokens[cursor] == '"' && token.value == "\"\\\"\"")) - { - tree->tag ("literal"); - tree->tag ("special"); - tree->attribute ("token", tokens[cursor]); - - if (_verbose) - std::cout << "tokenMatchSpecialLiteral " - << token.value - << " SUCCEED" - << std::endl; - - cursor++; - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool LRParser::tokenMatchLiteral ( - const Token& token, - unsigned int& cursor, - const std::string& tokens, - Tree* tree) -{ - int len = token.value.length () - 2; - if (cursor > tokens.length () - len) return false; - - std::string tok = token.value.substr (1, len); - - if (token.value[0] == '"' && - token.value[len + 1] == '"' && - tokens.find (tok, cursor) == cursor) - { - tree->tag ("literal"); - tree->attribute ("token", tok); - cursor += len; - - if (_verbose) - std::cout << "tokenMatchLiteral " - << token.value - << " SUCCEED" - << std::endl; - - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool LRParser::tokenMatchRegex ( - const Token& token, - unsigned int& cursor, - const std::string& tokens, - Tree* tree) -{ - if (cursor >= tokens.length () - 1) return false; - - // If it looks like a regex. - if (token.value[0] == '/' && - token.value[token.value.length () - 1] == '/') - { - // If the regex matches at all. - RX rx ("(" + token.value.substr (1, token.value.length () - 2) + ")", false); - std::vector start; - std::vector end; - if (rx.match (start, - end, - tokens.substr (cursor, std::string::npos))) - { - // If the match is at position 'cursor'. - if (start[0] == 0) - { - tree->tag ("regex"); - tree->attribute ("token", tokens.substr (cursor + start[0], end[0])); - cursor += end[0]; - - if (_verbose) - std::cout << "tokenMatchRegex \"" - << tokens.substr (cursor + start[0], end[0]) - << "\"" - << " SUCCEED" - << std::endl; - - return true; - } - } - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool LRParser::tokenMatchRule ( - const std::string& rule, - char quantifier, - unsigned int alt, - unsigned int it, - const Token& token, - unsigned int& cursor, - const std::string& tokens, - Tree* tree) -{ - if (cursor >= tokens.length ()) return false; - - // If this is a definition, recurse. - if (_rules.find (token.value) != _rules.end ()) - { - if (_verbose) - std::cout << "tokenMatchRule " - << rule - << quantifier - << "/a" - << alt - << "/t" - << it - << " tokens[" - << cursor - << "]=" - << visible (tokens[cursor]) - << " token=" - << token.value - << " RECURSING matchRuleQuant" - << std::endl; - - return matchRuleQuant (token.value, token.quantifier, cursor, tokens, tree); - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/LRParser.h b/src/LRParser.h deleted file mode 100644 index fe761aa79..000000000 --- a/src/LRParser.h +++ /dev/null @@ -1,58 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// taskwarrior - a command line task list manager. -// -// Copyright 2006-2013, Paul Beckingham, Federico Hernandez. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// http://www.opensource.org/licenses/mit-license.php -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef INCLUDED_LRPARSER -#define INCLUDED_LRPARSER - -#include -#include - -class LRParser : public Parser -{ -public: - LRParser (); - Tree* parse (const std::string&); - void addEntity (const std::string&, const std::string&); - -private: - bool matchRuleQuant (const std::string&, char, unsigned int&, const std::string&, Tree*); - bool matchRule (const std::string&, char, unsigned int&, const std::string&, Tree*); - bool matchAlternate (const std::string&, char, unsigned int, const Alternate&, unsigned int&, const std::string&, Tree*); - bool matchToken (const std::string&, char, unsigned int, unsigned int, const Token&, unsigned int&, const std::string&, Tree*); - - bool tokenMatchSpecialLiteral (const Token&, unsigned int&, const std::string&, Tree*); - bool tokenMatchLiteral (const Token&, unsigned int&, const std::string&, Tree*); - bool tokenMatchRegex (const Token&, unsigned int&, const std::string&, Tree*); - bool tokenMatchRule (const std::string&, char, unsigned int, unsigned int, const Token&, unsigned int&, const std::string&, Tree*); - -private: - std::multimap _entities; -}; - -#endif - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/Parser.cpp b/src/Parser.cpp deleted file mode 100644 index 1ae580ff8..000000000 --- a/src/Parser.cpp +++ /dev/null @@ -1,390 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// taskwarrior - a command line task list manager. -// -// Copyright 2006-2013, Paul Beckingham, Federico Hernandez. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// http://www.opensource.org/licenses/mit-license.php -// -//////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include -#include - -//////////////////////////////////////////////////////////////////////////////// -Parser::Parser () -: _primary ("") -, _verbose (false) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Parser::~Parser () -{ -} - -//////////////////////////////////////////////////////////////////////////////// -void Parser::grammar (const std::string& file) -{ - // Strip comments. - std::vector lines; - split (lines, file, '\n'); - - std::string stripped = ""; - std::string::size_type comment; - std::vector ::iterator it; - for (it = lines.begin (); it != lines.end (); ++it) - { - comment = it->find ("#"); - - if (comment != std::string::npos) - stripped += it->substr (0, comment); - else - stripped += *it; - - stripped += "\n"; - } - - // Now parse the grammar. - Nibbler n (stripped); - std::string rule; - Production prod; - while (bnfNibbleRule (n, rule, prod)) - { - if (_primary == "") - _primary = rule; - - _rules[rule] = prod; - } - - // Now the hard part. - checkConsistency (); -} - -//////////////////////////////////////////////////////////////////////////////// -bool Parser::bnfNibbleRule (Nibbler& n, std::string& rule, Production& prod) -{ - prod.clear (); - n.skipWS (); - if (n.getUntilOneOf (": ", rule)) - { - std::string att; - while (n.skip (':') && - n.getUntilOneOf (": ", att)) - { - prod.tag (att); - } - - // Definition. - n.skipWS (); - if (n.getLiteral ("::=")) - { - // Alternates. - Alternate alt; - while (bnfNibbleAlternate (n, alt)) - { - prod.push_back (alt); - alt.clear (); - } - - if (alt.size ()) - prod.push_back (alt); - - return true; - } - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Parser::bnfNibbleAlternate (Nibbler& n, Alternate& alt) -{ - n.skipWS (); - - Token tok; - while (bnfNibbleToken (n, tok)) - alt.push_back (tok); - - if (n.skip ('|')) {return true;} - else if (n.skip (';')) {return false;} - else - throw std::string ("Expected | or ;"); -} - -//////////////////////////////////////////////////////////////////////////////// -bool Parser::bnfNibbleToken (Nibbler& n, Token& tok) -{ - tok.clear (); - n.skipWS (); - - if (n.next () == '|') return false; // Alternate - if (n.next () == ';') return false; // Terminator - - if (n.getQuoted ('/', tok.value, true) || // Regex - n.getQuoted ('"', tok.value, true) || // Literal - n.getUntilOneOf ("\n\t =?+*", tok.value)) // Name - { - if (n.skip ('=')) tok.quantifier = '='; // 1 - else if (n.skip ('?')) tok.quantifier = '?'; // 0,1 - else if (n.skip ('+')) tok.quantifier = '+'; // 1-> - else if (n.skip ('*')) tok.quantifier = '*'; // 0-> - - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// Check consistency of the syntax. This is where all static analysis occurs. -void Parser::checkConsistency () -{ - std::vector allRules; - std::vector allToken; - std::vector allLeftRecursive; - - std::map ::iterator r; - for (r = _rules.begin (); r != _rules.end (); ++r) - { - allRules.push_back (r->first); - - std::vector ::iterator a; - for (a = r->second.begin (); a != r->second.end (); ++a) - { - std::vector ::iterator i; - for (i = a->begin (); i != a->end (); ++i) - { - if (i->value[0] != '"' && - i->value[0] != '/') - allToken.push_back (i->value); - - if (i == a->begin () && r->first == i->value) - allLeftRecursive.push_back (i->value); - } - } - } - - std::vector notUsed; - std::vector notDefined; - listDiff (allRules, allToken, notUsed, notDefined); - - // Undefined value - these are definitions that appear in token, but are - // not in _rules. - for (unsigned int i = 0; i < notDefined.size (); ++i) - if (notDefined[i][0] != '@') - throw std::string ("definition '") + notDefined[i] + "' referenced, but not defined."; - - // Circular definitions - these are names in _rules that also appear as - // token 0 in any of the alternates for that definition. - for (unsigned int i = 0; i < allLeftRecursive.size (); ++i) - throw std::string ("definition '") + allLeftRecursive[i] + "' is left recursive."; - - for (unsigned int i = 0; i < allRules.size (); ++i) - if (allRules[i][0] == '"') - throw std::string ("definition '") + allRules[i] + "' must not be a literal."; - - // Unused definitions - these are names in _rules that are never - // referenced as token. - for (unsigned int i = 0; i < notUsed.size (); ++i) - if (notUsed[i] != _primary) - throw std::string ("definition '") + notUsed[i] + "' defined, but not referenced."; -} - -//////////////////////////////////////////////////////////////////////////////// -void Parser::verbose () -{ - _verbose = true; -} - -//////////////////////////////////////////////////////////////////////////////// -// Display the entire parsed tree. Highlight the primary definition. -void Parser::dump () const -{ - std::map ::const_iterator def; - for (def = _rules.begin (); def != _rules.end (); ++def) - { - if (def->first == _primary) - std::cout << "\033[1m" << def->first << "\033[0m"; - else - std::cout << def->first; - - std::cout << " ::=" << std::endl; - - std::vector ::const_iterator alt; - for (alt = def->second.begin (); alt != def->second.end (); ++alt) - { - if (alt != def->second.begin ()) - std::cout << " | "; - else - std::cout << " "; - - std::vector ::const_iterator tok; - for (tok = alt->begin (); tok != alt->end (); ++tok) - { - std::cout << tok->value; - - if (tok->quantifier != '=') - std::cout << tok->quantifier; - - std::cout << " "; - } - - std::cout << std::endl; - } - - std::cout << " ;" << std::endl; - } -} - -//////////////////////////////////////////////////////////////////////////////// -Parser::Token::Token () -: value ("") -, quantifier ('=') -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Parser::Token::Token (const Parser::Token& other) -: value (other.value) -, quantifier (other.quantifier) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Parser::Token& Parser::Token::operator= (const Parser::Token& other) -{ - if (this != &other) - { - value = other.value; - quantifier = other.quantifier; - } - - return *this; -} - -//////////////////////////////////////////////////////////////////////////////// -void Parser::Token::clear () -{ - value = ""; - quantifier = '='; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Parser::Token::dump () -{ - return value + quantifier; -} - -//////////////////////////////////////////////////////////////////////////////// -Parser::Alternate::Alternate () -: std::vector () -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Parser::Alternate::Alternate (const Parser::Alternate& other) -: std::vector (other) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Parser::Alternate& Parser::Alternate::operator= (const Parser::Alternate& other) -{ - if (this != &other) - std::vector ::operator= (other); - - return *this; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Parser::Alternate::dump () -{ - std::string result; - std::vector ::iterator i; - for (i = this->begin (); i != this->end (); ++i) - result += i->dump () + ' '; - return result; -} - -//////////////////////////////////////////////////////////////////////////////// -Parser::Production::Production () -: std::vector () -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Parser::Production::Production (const Parser::Production& other) -: std::vector (other) -, mTags (other.mTags) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Parser::Production& Parser::Production::operator= (const Parser::Production& other) -{ - if (this != &other) - { - std::vector ::operator= (other); - mTags = other.mTags; - } - - return *this; -} - -//////////////////////////////////////////////////////////////////////////////// -void Parser::Production::tag (const std::string& t) -{ - mTags.push_back (t); -} - -//////////////////////////////////////////////////////////////////////////////// -bool Parser::Production::hasTag (const std::string& t) const -{ - return std::find (mTags.begin (), mTags.end (), t) != mTags.end () - ? true : false; -} - -//////////////////////////////////////////////////////////////////////////////// -void Parser::Production::clear () -{ - std::vector ::clear (); - mTags.clear (); -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Parser::Production::dump () -{ - std::string result; - std::vector ::iterator i; - for (i = this->begin (); i != this->end (); ++i) - { - if (i != this->begin ()) - result += " | "; - result += i->dump (); - } - - result += "\n"; - return result; -} - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/Parser.h b/src/Parser.h deleted file mode 100644 index 224dae580..000000000 --- a/src/Parser.h +++ /dev/null @@ -1,103 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// taskwarrior - a command line task list manager. -// -// Copyright 2006-2013, Paul Beckingham, Federico Hernandez. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// http://www.opensource.org/licenses/mit-license.php -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef INCLUDED_PARSER -#define INCLUDED_PARSER - -#include -#include -#include -#include -#include -#include - -class Parser -{ -public: - Parser (); - virtual ~Parser (); - void grammar (const std::string&); - virtual Tree* parse (const std::string&) = 0; - - void verbose (); - void dump () const; - -protected: - class Token - { - public: - Token (); - Token (const Token&); - Token& operator= (const Token&); - void clear (); - std::string dump (); - - public: - std::string value; - char quantifier; - }; - - class Alternate : public std::vector - { - public: - Alternate (); - Alternate (const Alternate&); - Alternate& operator= (const Alternate&); - std::string dump (); - }; - - class Production : public std::vector - { - public: - Production (); - Production (const Production&); - Production& operator= (const Production&); - void tag (const std::string&); - bool hasTag (const std::string&) const; - void clear (); - std::string dump (); - - private: - std::vector mTags; - }; - -private: - bool bnfNibbleRule (Nibbler&, std::string&, Production&); - bool bnfNibbleAlternate (Nibbler&, Alternate&); - bool bnfNibbleToken (Nibbler&, Token&); - - void checkConsistency (); - -protected: - std::string _primary; - std::map _rules; - bool _verbose; -}; - -#endif - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/bnf.cpp b/src/bnf.cpp deleted file mode 100644 index 2a138c6cf..000000000 --- a/src/bnf.cpp +++ /dev/null @@ -1,134 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// taskwarrior - a command line task list manager. -// -// Copyright 2006-2013, Paul Beckingham, Federico Hernandez. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// http://www.opensource.org/licenses/mit-license.php -// -//////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -Context context; - -//////////////////////////////////////////////////////////////////////////////// -void usage () -{ - std::cout << std::endl - << "Usage: parser [options] " - << std::endl - << std::endl - << "Options are:" - << std::endl - << " -v/--verbose Increased verbosity" - << std::endl - << std::endl; - - exit (-1); -} - -//////////////////////////////////////////////////////////////////////////////// -int main (int argc, char** argv) -{ - // Process command line arguments - std::string grammarFile = ""; - std::string commandLine = ""; - std::vector args; - bool verbose = false; - - for (int i = 1; i < argc; ++i) - { - if (argv[i][0] == '-') - { - if (!strcmp (argv[i], "-h")) usage (); - else if (!strcmp (argv[i], "--help")) usage (); - else if (!strcmp (argv[i], "-v")) verbose = true; - else if (!strcmp (argv[i], "--verbose")) verbose = true; - else - { - std::cout << "Unrecognized option '" << argv[i] << "'" << std::endl; - usage (); - } - } - else if (grammarFile == "") - { - grammarFile = argv[i]; - std::cout << "INFO: Using grammar file " << grammarFile << "\n"; - } - else - { - if (commandLine != "") - commandLine += " "; - - commandLine += "'" + std::string (argv[i]) + "'"; - } - } - - // Display usage for incorrect command line. - if (grammarFile == "" || commandLine == "") - usage (); - - try - { - std::string grammar; - if (File::read (grammarFile, grammar)) - { - // Parse the tokens. - LRParser p; - if (verbose) p.verbose (); - - // TODO Initialize entity lists. - p.addEntity ("report", "list"); - p.addEntity ("writecmd", "modify"); - - // Load and verify grammar. - p.grammar (grammar); - if (verbose) p.dump (); - - // Either returns a parse-tree or throws. - std::cout << "INFO: Parsing <" << commandLine << ">\n"; - Tree* t = p.parse (commandLine); - if (t) - { - t->dump (); - delete t; - } - } - } - - catch (const std::string& error) - { - std::cout << "Error: " << error << std::endl; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////////////