Grammar: Code cleanup

This commit is contained in:
Paul Beckingham 2015-12-22 08:26:33 -05:00
parent 6c581fb8c2
commit 83d7134d64
2 changed files with 27 additions and 17 deletions

View file

@ -38,14 +38,12 @@ Grammar::Grammar ()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Grammar::loadFromFile (File& file) void Grammar::loadFromFile (File& file)
{ {
if (file.exists ()) if (! file.exists ())
{ throw format ("Grammar file '{1}' not found.", file._data);
std::string contents;
file.read (contents); std::string contents;
loadFromString (contents); file.read (contents);
} loadFromString (contents);
else
throw format ("Grammar file '{1}' not found.", static_cast<std::string> (file));
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -70,8 +68,8 @@ void Grammar::loadFromFile (File& file)
void Grammar::loadFromString (const std::string& input) void Grammar::loadFromString (const std::string& input)
{ {
std::string rule_name = ""; std::string rule_name = "";
int token_count = 0;
// This is a state machine. Read each line.
for (auto& line : split (input, '\n')) for (auto& line : split (input, '\n'))
{ {
// Skip whole-line comments. // Skip whole-line comments.
@ -83,15 +81,14 @@ void Grammar::loadFromString (const std::string& input)
if (hash != std::string::npos) if (hash != std::string::npos)
line.resize (hash); line.resize (hash);
line = Lexer::trim (line);
// Skip blank lines with no semantics. // Skip blank lines with no semantics.
line = Lexer::trim (line);
if (line == "" and rule_name == "") if (line == "" and rule_name == "")
continue; continue;
if (line != "") if (line != "")
{ {
token_count = 0; int token_count = 0;
Lexer l (line); Lexer l (line);
Lexer::Type type; Lexer::Type type;
@ -102,7 +99,10 @@ void Grammar::loadFromString (const std::string& input)
if (token.back () == ':') if (token.back () == ':')
{ {
// Capture the Rule_name.
rule_name = token.substr (0, token.size () - 1); rule_name = token.substr (0, token.size () - 1);
// If this is the first Rule, capture it as a starting point.
if (_start == "") if (_start == "")
_start = rule_name; _start = rule_name;
@ -111,22 +111,30 @@ void Grammar::loadFromString (const std::string& input)
} }
else if (token.front () == ':') else if (token.front () == ':')
{ {
// Decorate the most recent token, of the most recent production, // Decorate the most recent token, of the most recent Production,
// of the current rule. // of the current Rule.
_rules[rule_name].back ().back ().decorate (token); _rules[rule_name].back ().back ().decorate (token);
} }
else else
{ {
// If no Production was added yet, add one.
if (token_count <= 1) if (token_count <= 1)
_rules[rule_name].push_back (Grammar::Production ()); _rules[rule_name].push_back (Grammar::Production ());
// Add the new Token to the most recent Production, of the current
// Rule.
_rules[rule_name].back ().push_back (Grammar::Token (token)); _rules[rule_name].back ().push_back (Grammar::Token (token));
} }
} }
} }
// A blank line in the input ends the current rule definition.
else else
rule_name = ""; rule_name = "";
} }
// Validate the parsed grammar.
validate ();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -135,6 +143,7 @@ std::string Grammar::dump () const
std::stringstream out; std::stringstream out;
for (auto& rule : _rules) for (auto& rule : _rules)
{ {
// Indicate the start Rule.
if (rule.first == _start) if (rule.first == _start)
out << ""; out << "";
@ -145,9 +154,10 @@ std::string Grammar::dump () const
out << " "; out << " ";
for (auto& term : production) for (auto& term : production)
{ {
out << term._token << " "; out << term._token;
if (term._decoration != "") if (term._decoration != "")
out << "(" << term._decoration << ") "; out << term._decoration;
out << " ";
} }
out << "\n"; out << "\n";

View file

@ -48,7 +48,7 @@ int main (int argc, const char** argv)
// TODO Load CLI grammar. // TODO Load CLI grammar.
// TODO Load from string, else file on config override. // TODO Load from string, else file on config override.
// TODO Migrate from loading a grammar from file, to a string. // TODO Migrate from loading a grammar from file, to a default string.
File file ("./grammar.cfg"); File file ("./grammar.cfg");
Grammar grammar; Grammar grammar;
grammar.loadFromFile (file); grammar.loadFromFile (file);