Code Cleanup

- Removed obsolete parser code.
This commit is contained in:
Paul Beckingham 2014-01-02 01:58:20 -05:00
parent eb7c8e2365
commit 5409d014c5
6 changed files with 0 additions and 1161 deletions

View file

@ -23,11 +23,9 @@ set (task_SRCS A3.cpp A3.h
ISO8601.cpp ISO8601.h ISO8601.cpp ISO8601.h
JSON.cpp JSON.h JSON.cpp JSON.h
Lexer.cpp Lexer.h Lexer.cpp Lexer.h
LRParser.cpp LRParser.h
Msg.cpp Msg.h Msg.cpp Msg.h
Nibbler.cpp Nibbler.h Nibbler.cpp Nibbler.h
OldDuration.cpp OldDuration.h OldDuration.cpp OldDuration.h
Parser.cpp Parser.h
Path.cpp Path.h Path.cpp Path.h
RX.cpp RX.h RX.cpp RX.h
Socket.cpp Socket.h Socket.cpp Socket.h
@ -61,13 +59,11 @@ set (task_SRCS A3.cpp A3.h
add_library (task STATIC ${task_SRCS}) add_library (task STATIC ${task_SRCS})
add_executable (task_executable main.cpp) add_executable (task_executable main.cpp)
add_executable (calc_executable calc.cpp) add_executable (calc_executable calc.cpp)
add_executable (parser_executable bnf.cpp)
add_executable (args_executable args.cpp) add_executable (args_executable args.cpp)
# Yes, 'task' is included twice, otherwise linking fails on assorted OSes. # 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 (task_executable task commands columns task ${TASK_LIBRARIES})
target_link_libraries (calc_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}) target_link_libraries (args_executable task commands columns task ${TASK_LIBRARIES})
set_property (TARGET task_executable PROPERTY OUTPUT_NAME "task") 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}) install (TARGETS task_executable DESTINATION ${TASK_BINDIR})
set_property (TARGET calc_executable PROPERTY OUTPUT_NAME "calc") 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_property (TARGET args_executable PROPERTY OUTPUT_NAME "args")
#SET(CMAKE_BUILD_TYPE gcov) #SET(CMAKE_BUILD_TYPE gcov)

View file

@ -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 <iostream>
#include <LRParser.h>
#include <RX.h>
#include <text.h>
#include <main.h>
////////////////////////////////////////////////////////////////////////////////
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 <std::string, std::string> (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 <int> start;
std::vector <int> 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;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -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 <map>
#include <Parser.h>
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 <std::string, std::string> _entities;
};
#endif
////////////////////////////////////////////////////////////////////////////////

View file

@ -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 <iostream>
#include <Parser.h>
#include <text.h>
#include <main.h>
////////////////////////////////////////////////////////////////////////////////
Parser::Parser ()
: _primary ("")
, _verbose (false)
{
}
////////////////////////////////////////////////////////////////////////////////
Parser::~Parser ()
{
}
////////////////////////////////////////////////////////////////////////////////
void Parser::grammar (const std::string& file)
{
// Strip comments.
std::vector <std::string> lines;
split (lines, file, '\n');
std::string stripped = "";
std::string::size_type comment;
std::vector <std::string>::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 <std::string> allRules;
std::vector <std::string> allToken;
std::vector <std::string> allLeftRecursive;
std::map <std::string, Production>::iterator r;
for (r = _rules.begin (); r != _rules.end (); ++r)
{
allRules.push_back (r->first);
std::vector <Alternate>::iterator a;
for (a = r->second.begin (); a != r->second.end (); ++a)
{
std::vector <Token>::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 <std::string> notUsed;
std::vector <std::string> 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 <std::string, Production>::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 <Alternate>::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 <Token>::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::Token> ()
{
}
////////////////////////////////////////////////////////////////////////////////
Parser::Alternate::Alternate (const Parser::Alternate& other)
: std::vector <Parser::Token> (other)
{
}
////////////////////////////////////////////////////////////////////////////////
Parser::Alternate& Parser::Alternate::operator= (const Parser::Alternate& other)
{
if (this != &other)
std::vector <Parser::Token>::operator= (other);
return *this;
}
////////////////////////////////////////////////////////////////////////////////
std::string Parser::Alternate::dump ()
{
std::string result;
std::vector <Parser::Token>::iterator i;
for (i = this->begin (); i != this->end (); ++i)
result += i->dump () + ' ';
return result;
}
////////////////////////////////////////////////////////////////////////////////
Parser::Production::Production ()
: std::vector <Parser::Alternate> ()
{
}
////////////////////////////////////////////////////////////////////////////////
Parser::Production::Production (const Parser::Production& other)
: std::vector <Parser::Alternate> (other)
, mTags (other.mTags)
{
}
////////////////////////////////////////////////////////////////////////////////
Parser::Production& Parser::Production::operator= (const Parser::Production& other)
{
if (this != &other)
{
std::vector <Parser::Alternate>::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 <Parser::Alternate>::clear ();
mTags.clear ();
}
////////////////////////////////////////////////////////////////////////////////
std::string Parser::Production::dump ()
{
std::string result;
std::vector <Parser::Alternate>::iterator i;
for (i = this->begin (); i != this->end (); ++i)
{
if (i != this->begin ())
result += " | ";
result += i->dump ();
}
result += "\n";
return result;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -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 <algorithm>
#include <map>
#include <vector>
#include <string>
#include <Nibbler.h>
#include <Tree.h>
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 <Token>
{
public:
Alternate ();
Alternate (const Alternate&);
Alternate& operator= (const Alternate&);
std::string dump ();
};
class Production : public std::vector <Alternate>
{
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 <std::string> mTags;
};
private:
bool bnfNibbleRule (Nibbler&, std::string&, Production&);
bool bnfNibbleAlternate (Nibbler&, Alternate&);
bool bnfNibbleToken (Nibbler&, Token&);
void checkConsistency ();
protected:
std::string _primary;
std::map <std::string, Production> _rules;
bool _verbose;
};
#endif
////////////////////////////////////////////////////////////////////////////////

View file

@ -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 <iostream>
#include <fstream>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <Context.h>
#include <File.h>
#include <Tree.h>
#include <LRParser.h>
#include <text.h>
Context context;
////////////////////////////////////////////////////////////////////////////////
void usage ()
{
std::cout << std::endl
<< "Usage: parser [options] <grammar file> <args>"
<< 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 <std::string> 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;
}
////////////////////////////////////////////////////////////////////////////////