From eaf27867384ca839fbabb662bf4a833df1b2aa10 Mon Sep 17 00:00:00 2001 From: Robin Jadoul Date: Mon, 2 Jan 2017 17:02:43 +0100 Subject: [PATCH] Fixes for the c++ backend --- include/Parsodus/backends/cppLR.h | 33 ++++++++++++++------------- templates/c++/lr.cpp | 6 ++--- templates/c++/lr.h | 37 ++++++++++++++++--------------- 3 files changed, 39 insertions(+), 37 deletions(-) diff --git a/include/Parsodus/backends/cppLR.h b/include/Parsodus/backends/cppLR.h index 697fccd..c5ccfe5 100644 --- a/include/Parsodus/backends/cppLR.h +++ b/include/Parsodus/backends/cppLR.h @@ -51,11 +51,11 @@ namespace backends { topLevel["num_symbols"] = templ::make_string(std::to_string(config.grammar.terminals.size() + 1 + config.grammar.variables.size())); // + 1 for EOF std::vector symbols; - symbols.push_back(templ::make_map({{"symbol", "TEOF"}})); + symbols.push_back(templ::make_map({{"symbol", templ::make_string("T_EOF")}})); for (auto& s : config.grammar.terminals) - symbols.push_back(templ::make_map({{"symbol", s}})); + symbols.push_back(templ::make_map({{"symbol", templ::make_string("T_" + s)}})); for (auto& s : config.grammar.variables) - symbols.push_back(templ::make_map({{"symbol", s}})); + symbols.push_back(templ::make_map({{"symbol", templ::make_string("V_" + s)}})); topLevel["symbols"] = std::move(symbols); std::vector rules; @@ -64,7 +64,7 @@ namespace backends { r["index"] = templ::make_string(std::to_string(i)); r["rhs_length"] = templ::make_string(std::to_string(config.grammar.rules[i]->tail.size())); if (false /* the rule has a name */) - r["name"] = templ::make_string(""); //The name + r["rname"] = templ::make_string(""); //The name rules.push_back(templ::make_map(std::move(r))); } topLevel["rules"] = templ::make_array(std::move(rules)); @@ -76,8 +76,8 @@ namespace backends { std::map st; std::vector actions; - for (const auto& term : terminals) { - std::string a = ""; + for (std::string term : terminals) { + std::string a = "ERROR"; std::string data = "0"; if (table.act[i].find(term) != table.act[i].end()) { const auto& tmp = table.act[i][term]; @@ -88,7 +88,7 @@ namespace backends { break; case lr::Action::REDUCE: a = "REDUCE"; - data = term + " << 31 | " + std::to_string(tmp.second); + data = "static_cast(" + parserName + "_Symbol::V_" + config.grammar.rules[tmp.second]->head + ") << 31 | " + std::to_string(tmp.second); break; case lr::Action::ACCEPT: a = "ACCEPT"; @@ -101,22 +101,23 @@ namespace backends { actions.push_back(templ::make_map({{"action", templ::make_string(a)}, {"data", templ::make_string(data)}})); - std::vector gotos; - for (const auto& nonterm : config.grammar.variables) { - gotos.push_back(templ::make_string(std::to_string(table.goto_[i][nonterm]))); - } - - st["actions"] = templ::make_array(std::move(actions)); - st["gotos"] = templ::make_array(std::move(gotos)); - states[i] = templ::make_map(std::move(st)); } + + std::vector gotos; + for (const auto& nonterm : config.grammar.variables) { + gotos.push_back(templ::make_string(std::to_string(table.goto_[i][nonterm]))); + } + + st["actions"] = templ::make_array(std::move(actions)); + st["gotos"] = templ::make_array(std::move(gotos)); + states[i] = templ::make_map(std::move(st)); } topLevel["states"] = templ::make_array(std::move(states)); std::unique_ptr headerOut = getOstreamForFileName(parserName + ".h"); std::unique_ptr implOut = getOstreamForFileName(parserName + ".cpp"); this->doTemplate(*headerOut, "c++/lr.h", topLevel); - this->doTemplate(*implOut, "c++/lr.h", topLevel); + this->doTemplate(*implOut, "c++/lr.cpp", topLevel); } private: util::ParserType m_parserType; diff --git a/templates/c++/lr.cpp b/templates/c++/lr.cpp index 388fb34..6e9a2f2 100644 --- a/templates/c++/lr.cpp +++ b/templates/c++/lr.cpp @@ -5,9 +5,9 @@ const std::uint64_t TABLE[{{num_states}}][{{num_symbols}}] = { {{#states}} - { {{#actions}}({{name}}::{{action}} | {{data}} << 2),{{/actions}} - {{#gotos}}({{data}} << 2),{{/gotos}} }, + { {{#actions}}({{action}} | ({{data}}) << 2),{{/actions}} + {{#gotos}}(({{.}}) << 2),{{/gotos}} }, {{/states}} }; -const unsigned char REDUCE_COUNT[{{num_rules}}] = { {{#rules}}{{rhs_length}}{{/rules}} }; +const unsigned char REDUCE_COUNT[{{num_rules}}] = { {{#rules}}{{rhs_length}},{{/rules}} }; diff --git a/templates/c++/lr.h b/templates/c++/lr.h index a05015d..a416bef 100644 --- a/templates/c++/lr.h +++ b/templates/c++/lr.h @@ -3,9 +3,19 @@ #define PARSODUS_PARSER_{{name}}_H #include +#include #include #include +/** + * Represents the type of the symbol (both terminals and nonterminals) + */ +enum class {{name}}_Symbol : std::uint64_t { + {{#symbols}} + {{symbol}}, + {{/symbols}} +}; + template class {{name}} { public: @@ -19,21 +29,12 @@ class {{name}} { protected: - /** - * Represents the type of the symbol (both terminals and nonterminals) - */ - enum Symbol { - {{#symbols}} - {{symbol}}, - {{/symbols}} - } - /** * A token, consisting of a Symbol type (should be a terminal) and a Value */ struct Token { - Symbol symbol, - Value value + {{name}}_Symbol symbol; + Value value; }; @@ -50,8 +51,8 @@ class {{name}} { * Apply a reduction (a grammar rule in reverse) */ {{#rules}} - {{#name}}virtual Value reduce_{{name}}(std::deque subparts) = 0;{{/name}} - {{^name}}virtual Value reduce_{{index}}(std::deque subparts) = 0;{{/name}} + {{#rname}}virtual Value reduce_{{rname}}(std::deque subparts) = 0;{{/rname}} + {{^rname}}virtual Value reduce_{{index}}(std::deque subparts) = 0;{{/rname}} {{/rules}} private: @@ -75,7 +76,7 @@ enum Action { * Parser implementation * ***************************/ template -Value {{name}}::parse() { +Value {{name}}::parse() { std::stack valueStack; std::stack stateStack; @@ -98,11 +99,11 @@ Value {{name}}::parse() { case REDUCE: { std::uint64_t tmp = act >> 2; - Symbol symbol = tmp >> 31; + {{name}}_Symbol symbol = static_cast<{{name}}_Symbol>(tmp >> 31); std::uint32_t rule = tmp & ((1ull << 32) - 1); std::deque dq; - for (decltype(RECUDE_COUNT[rule]) i = 0; i < REDUCE_COUNT[rule]; i++) { + for (unsigned char i = 0; i < REDUCE_COUNT[rule]; i++) { dq.emplace_front(std::move(valueStack.top())); valueStack.pop(); stateStack.pop(); @@ -111,8 +112,8 @@ Value {{name}}::parse() { switch (rule) { {{#rules}} case {{index}}: - {{#name}}valueStack.emplace({symbol, reduce_{{name}}(std::move(dq))}){{/name}} - {{^name}}valueStack.emplace({symbol, reduce_{{index}}(std::move(dq))}){{/name}} + {{#rname}}valueStack.emplace({symbol, reduce_{{rname}}(std::move(dq))});{{/rname}} + {{^rname}}valueStack.emplace({symbol, reduce_{{index}}(std::move(dq))});{{/rname}} break; {{/rules}} default: