From 998c2f89b5afd19d1809692abfc4063acf2a78d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Raphael=20von=20der=20Gr=C3=BCn?= <raphinesse@gmail.com>
Date: Wed, 8 Apr 2020 16:06:10 +0200
Subject: [PATCH] Add option to auto-unwrap rule results

---
 lib/compile.js  | 27 +++++++++++++++++++++++----
 lib/generate.js |  1 +
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/lib/compile.js b/lib/compile.js
index c0ae8a16..03f584cc 100644
--- a/lib/compile.js
+++ b/lib/compile.js
@@ -68,7 +68,13 @@
                 };
             } else if (productionRule.config) {
                 // This isn't a rule, it's an @config.
-                result.config[productionRule.config] = productionRule.value
+
+                // Convert autoUnwrap config to boolean
+                var value = productionRule.config === 'autoUnwrap'
+                    ? productionRule.value === 'true'
+                    : productionRule.value;
+
+                result.config[productionRule.config] = value;
             } else {
                 produceRules(productionRule.name, productionRule.rules, {});
                 if (!result.start) {
@@ -97,10 +103,20 @@
                     tokens.push(token);
                 }
             }
+
+            var postprocess = rule.postprocess;
+            var shouldAutoUnwrap = Object.prototype.hasOwnProperty.call(rule, 'autoUnwrap')
+                ? rule.autoUnwrap
+                : result.config.autoUnwrap;
+
+            if (shouldAutoUnwrap && tokens.length === 1) {
+                postprocess = 'id._auto(' + (postprocess || '') + ')';
+            }
+
             return new nearley.Rule(
                 ruleName,
                 tokens,
-                rule.postprocess
+                postprocess
             );
         }
 
@@ -169,7 +185,8 @@
                             literal: d
                         };
                     }),
-                    postprocess: {builtin: "joiner"}
+                    postprocess: {builtin: "joiner"},
+                    autoUnwrap: false,
                 }
             ], env);
             return newname;
@@ -210,6 +227,7 @@
             produceRules(name,
                 [{
                     tokens: [token.ebnf],
+                    autoUnwrap: false,
                 }, {
                     tokens: [name, token.ebnf],
                     postprocess: {builtin: "arrpush"}
@@ -261,7 +279,8 @@
             produceRules(name,
                 [{
                     tokens: [token.ebnf],
-                    postprocess: {builtin: "id"}
+                    postprocess: {builtin: "id"},
+                    autoUnwrap: false,
                 }, {
                     tokens: [],
                     postprocess: {builtin: "nuller"}
diff --git a/lib/generate.js b/lib/generate.js
index e9e88664..66a6971c 100644
--- a/lib/generate.js
+++ b/lib/generate.js
@@ -114,6 +114,7 @@
         output +=  "// http://github.com/Hardmath123/nearley\n";
         output += "(function () {\n";
         output += "function id(x) { return x[0]; }\n";
+        output += "id._auto = function(fn) { return fn ? function(d, l, r) { return fn(id(d), l, r); } : id; };";
         output += parser.body.join('\n');
         output += "var grammar = {\n";
         output += "    Lexer: " + parser.config.lexer + ",\n";