Parser template implementation
This commit is contained in:
parent
a4cd31c011
commit
85d5142c60
|
@ -2,7 +2,9 @@
|
||||||
#ifndef PARSODUS_PARSER_{{name}}_H
|
#ifndef PARSODUS_PARSER_{{name}}_H
|
||||||
#define PARSODUS_PARSER_{{name}}_H
|
#define PARSODUS_PARSER_{{name}}_H
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
template <typename Value>
|
template <typename Value>
|
||||||
class {{name}} {
|
class {{name}} {
|
||||||
|
@ -48,15 +50,25 @@ class {{name}} {
|
||||||
* Apply a reduction (a grammar rule in reverse)
|
* Apply a reduction (a grammar rule in reverse)
|
||||||
*/
|
*/
|
||||||
{{#rules}}
|
{{#rules}}
|
||||||
{{#name}}virtual Value reduce_{{name}}(const std::deque<Token>& subparts) = 0;{{/name}}
|
{{#name}}virtual Token reduce_{{name}}(std::deque<Token> subparts) = 0;{{/name}}
|
||||||
{{^name}}virtual Value reduce_{{index}}(const std::deque<Token>& subparts) = 0;{{/name}}
|
{{^name}}virtual Token reduce_{{index}}(std::deque<Token> subparts) = 0;{{/name}}
|
||||||
{{/rules}}
|
{{/rules}}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TABLE {{name}}___Table___{{name}}
|
||||||
|
#define REDUCE_COUNT {{name}}___Num_Reduces___{{name}}
|
||||||
// Not a static member because the table should not be replicated for different instantiations of the parser
|
// Not a static member because the table should not be replicated for different instantiations of the parser
|
||||||
extern const std::uint64_t {{name}}___Table[%(num_states)][%(num_symbols)];
|
extern const std::uint64_t TABLE[%(num_states)][%(num_symbols)];
|
||||||
|
extern const unsigned char REDUCE_COUNT[%(num_rules)];
|
||||||
|
|
||||||
|
enum Action {
|
||||||
|
ERROR = 0,
|
||||||
|
SHIFT = 1,
|
||||||
|
REDUCE = 2,
|
||||||
|
ACCEPT = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/***************************
|
/***************************
|
||||||
|
@ -64,7 +76,61 @@ extern const std::uint64_t {{name}}___Table[%(num_states)][%(num_symbols)];
|
||||||
***************************/
|
***************************/
|
||||||
template <typename Value>
|
template <typename Value>
|
||||||
Value {{name}}::parse() {
|
Value {{name}}::parse() {
|
||||||
//TODO
|
std::stack<Token> valueStack;
|
||||||
|
std::stack<std::uint64_t> stateStack;
|
||||||
|
|
||||||
|
stateStack.push(0);
|
||||||
|
Token tok = lex();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
std::uint64_t act = TABLE[stateStack.top()][tok.symbol];
|
||||||
|
|
||||||
|
switch (act & 0x3) {
|
||||||
|
case ERROR:
|
||||||
|
//TODO: error handling
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
case SHIFT:
|
||||||
|
valueStack.emplace(std::move(tok));
|
||||||
|
stateStack.push(act >> 2);
|
||||||
|
tok = lex();
|
||||||
|
break;
|
||||||
|
case REDUCE:
|
||||||
|
{
|
||||||
|
std::uint64_t rule = act >> 2;
|
||||||
|
std::deque<Token> dq;
|
||||||
|
for (decltype(RECUDE_COUNT[rule]) i = 0; i < REDUCE_COUNT[rule]; i++) {
|
||||||
|
dq.emplace_front(std::move(valueStack.top()));
|
||||||
|
valueStack.pop();
|
||||||
|
stateStack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (rule) {
|
||||||
|
{{#rules}}
|
||||||
|
case {{index}}:
|
||||||
|
{{#name}}valueStack.emplace(reduce_{{name}}(std::move(dq))){{/name}}
|
||||||
|
{{^name}}valueStack.emplace(reduce{{index}}(std::move(dq))){{/name}}
|
||||||
|
break;
|
||||||
|
{{/rules}}
|
||||||
|
default:
|
||||||
|
assert(false); //There should be no such rule
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
stateStack.push(TABLE[stateStack.top()][valueStack.top().symbol] >> 2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ACCEPT:
|
||||||
|
assert(stateStack.size() == 2);
|
||||||
|
assert(valueStack.size() == 1);
|
||||||
|
return valueStack.top().value;
|
||||||
|
default:
|
||||||
|
//IMPOSSIBLE
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#undef REDUCE_COUNT
|
||||||
|
#undef TABLE
|
||||||
|
|
||||||
#endif /* PARSODUS_PARSER_{{name}}_H */
|
#endif /* PARSODUS_PARSER_{{name}}_H */
|
||||||
|
|
Loading…
Reference in New Issue