From 06b1ef75e1e631eecfb64e875a95d0a4a49a2707 Mon Sep 17 00:00:00 2001
From: Robin Jadoul <robin.jadoul@gmail.com>
Date: Sun, 1 Jan 2017 13:16:24 +0100
Subject: [PATCH] Don't require the user to specify the symbol type for a
 reduce rule

---
 templates/c++/lr.h | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/templates/c++/lr.h b/templates/c++/lr.h
index d58d1c6..1b8871b 100644
--- a/templates/c++/lr.h
+++ b/templates/c++/lr.h
@@ -50,8 +50,8 @@ class {{name}} {
          * Apply a reduction (a grammar rule in reverse)
          */
         {{#rules}}
-        {{#name}}virtual Token reduce_{{name}}(std::deque<Token> subparts) = 0;{{/name}}
-        {{^name}}virtual Token reduce_{{index}}(std::deque<Token> subparts) = 0;{{/name}}
+        {{#name}}virtual Value reduce_{{name}}(std::deque<Token> subparts) = 0;{{/name}}
+        {{^name}}virtual Value reduce_{{index}}(std::deque<Token> subparts) = 0;{{/name}}
         {{/rules}}
 
     private:
@@ -97,7 +97,10 @@ Value {{name}}::parse() {
                 break;
             case REDUCE:
                 {
-                    std::uint64_t rule = act >> 2;
+                    std::uint64_t tmp = act >> 2;
+                    Symbol symbol = tmp >> 31;
+                    std::uint32_t rule = tmp & ((1ull << 32) - 1);
+
                     std::deque<Token> dq;
                     for (decltype(RECUDE_COUNT[rule]) i = 0; i < REDUCE_COUNT[rule]; i++) {
                         dq.emplace_front(std::move(valueStack.top()));
@@ -108,8 +111,8 @@ Value {{name}}::parse() {
                     switch (rule) {
                         {{#rules}}
                         case {{index}}:
-                            {{#name}}valueStack.emplace(reduce_{{name}}(std::move(dq))){{/name}}
-                            {{^name}}valueStack.emplace(reduce{{index}}(std::move(dq))){{/name}}
+                            {{#name}}valueStack.emplace({symbol, reduce_{{name}}(std::move(dq))}){{/name}}
+                            {{^name}}valueStack.emplace({symbol, reduce_{{index}}(std::move(dq))}){{/name}}
                             break;
                         {{/rules}}
                         default: