/* * This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source distribution. */ #include "{{name}}.h" #define TABLE {{name}}___Table___{{name}} #define REDUCE_COUNT {{name}}___Num_Reduces___{{name}} const std::uint64_t TABLE[{{num_states}}][{{num_symbols}}] = { {{#states}} { {{#actions}}({{action}} | ({{data}}) << 2),{{/actions}} {{#gotos}}(({{.}}) << 2),{{/gotos}} }, {{/states}} }; 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; } } }