From 5c925b3868d91b278c4fe6f760032c2371bfb436 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 6 Feb 2019 09:31:32 -0800 Subject: [PATCH] cli: Check that extra rules aren't passed to functions like 'optional' Fixes #247 --- cli/src/generate/dsl.js | 45 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/cli/src/generate/dsl.js b/cli/src/generate/dsl.js index 1a9bed20..c18ac530 100644 --- a/cli/src/generate/dsl.js +++ b/cli/src/generate/dsl.js @@ -42,14 +42,17 @@ function choice(...elements) { } function optional(value) { + checkArguments(arguments.length, optional, 'optional'); return choice(value, blank()); } function prec(number, rule) { - if (rule == null) { - rule = number; - number = 0; - } + checkArguments( + arguments.length - 1, + prec, + 'prec', + ' and a precedence argument' + ); return { type: "PREC", @@ -64,6 +67,13 @@ prec.left = function(number, rule) { number = 0; } + checkArguments( + arguments.length - 1, + prec.left, + 'prec.left', + ' and an optional precedence argument' + ); + return { type: "PREC_LEFT", value: number, @@ -77,6 +87,13 @@ prec.right = function(number, rule) { number = 0; } + checkArguments( + arguments.length - 1, + prec.right, + 'prec.right', + ' and an optional precedence argument' + ); + return { type: "PREC_RIGHT", value: number, @@ -85,6 +102,13 @@ prec.right = function(number, rule) { } prec.dynamic = function(number, rule) { + checkArguments( + arguments.length - 1, + prec.dynamic, + 'prec.dynamic', + ' and a precedence argument' + ); + return { type: "PREC_DYNAMIC", value: number, @@ -93,6 +117,7 @@ prec.dynamic = function(number, rule) { } function repeat(rule) { + checkArguments(arguments.length, repeat, 'repeat'); return { type: "REPEAT", content: normalize(rule) @@ -100,6 +125,7 @@ function repeat(rule) { } function repeat1(rule) { + checkArguments(arguments.length, repeat1, 'repeat1'); return { type: "REPEAT1", content: normalize(rule) @@ -315,6 +341,17 @@ function grammar(baseGrammar, options) { return {name, word, rules, extras, conflicts, externals, inline}; } +function checkArguments(ruleCount, caller, callerName, suffix = '') { + if (ruleCount > 1) { + const error = new Error([ + `The \`${callerName}\` function only takes one rule argument${suffix}.`, + 'You passed multiple rules. Did you mean to call `seq`?\n' + ].join('\n')); + Error.captureStackTrace(error, caller); + throw error + } +} + global.alias = alias; global.blank = blank; global.choice = choice;