diff --git a/templates/c++/lr.cpp b/templates/c++/lr.cpp index 6e9a2f2..10b4edb 100644 --- a/templates/c++/lr.cpp +++ b/templates/c++/lr.cpp @@ -11,3 +11,44 @@ const std::uint64_t TABLE[{{num_states}}][{{num_symbols}}] = { }; const unsigned char REDUCE_COUNT[{{num_rules}}] = { {{#rules}}{{rhs_length}},{{/rules}} }; + + +bool {{name}}::parse() { + std::stack stateStack; + using Sym = {{name}}_Symbol; + + stateStack.push(0); + Sym tok = lex(); + + while (true) { + std::uint64_t act = TABLE[stateStack.top()][static_cast(tok)]; + + switch (act & 0x3) { + case ERROR: + return false; + case SHIFT: + stateStack.push(act >> 2); + tok = lex(); + break; + case REDUCE: + { + std::uint64_t tmp = act >> 2; + Sym symbol = static_cast(tmp >> 31); + std::uint32_t rule = tmp & ((1ull << 31) - 1); + + for (unsigned char i = 0; i < REDUCE_COUNT[rule]; i++) { + stateStack.pop(); + } + + stateStack.push(TABLE[stateStack.top()][static_cast(symbol)] >> 2); + } + break; + case ACCEPT: + assert(stateStack.size() == 2); + return true; + default: + //IMPOSSIBLE + break; + } + } +} diff --git a/templates/c++/lr.h b/templates/c++/lr.h index 71df638..9c44c23 100644 --- a/templates/c++/lr.h +++ b/templates/c++/lr.h @@ -82,7 +82,7 @@ class {{name}} { /** * Parse it */ - Value parse(); + bool parse(); protected: /****************************************** @@ -224,46 +224,6 @@ Value {{name}}::parse() { } } -template <> -Value {{name}}::parse() { - std::stack stateStack; - using Sym = {{name}}_Symbol; - - stateStack.push(0); - Sym tok = lex(); - - while (true) { - std::uint64_t act = TABLE[stateStack.top()][static_cast(tok)]; - - switch (act & 0x3) { - case ERROR: - return false; - case SHIFT: - stateStack.push(act >> 2); - tok = lex(); - break; - case REDUCE: - { - std::uint64_t tmp = act >> 2; - Sym symbol = static_cast(tmp >> 31); - std::uint32_t rule = tmp & ((1ull << 31) - 1); - - for (unsigned char i = 0; i < REDUCE_COUNT[rule]; i++) { - stateStack.pop(); - } - - stateStack.push(TABLE[stateStack.top()][static_cast(symbol)] >> 2); - } - break; - case ACCEPT: - assert(stateStack.size() == 2); - return true; - default: - //IMPOSSIBLE - break; - } - } -} #undef REDUCE_COUNT #undef TABLE