Report duplicate rule definitions as errors

Based on a pull request by Futago-za Ryuu (@futagoza):

  https://github.com/pegjs/pegjs/pull/329

Resolves #318.
redux
David Majda 8 years ago
parent 149c829897
commit eb5875bc6a

@ -19,16 +19,17 @@ var compiler = {
*/
passes: {
check: {
reportMissingRules: require("./passes/report-missing-rules"),
reportLeftRecursion: require("./passes/report-left-recursion"),
reportInfiniteLoops: require("./passes/report-infinite-loops")
reportMissingRules: require("./passes/report-missing-rules"),
reportDuplicateRules: require("./passes/report-duplicate-rules"),
reportLeftRecursion: require("./passes/report-left-recursion"),
reportInfiniteLoops: require("./passes/report-infinite-loops")
},
transform: {
removeProxyRules: require("./passes/remove-proxy-rules")
removeProxyRules: require("./passes/remove-proxy-rules")
},
generate: {
generateBytecode: require("./passes/generate-bytecode"),
generateJS: require("./passes/generate-js")
generateBytecode: require("./passes/generate-bytecode"),
generateJS: require("./passes/generate-js")
}
},

@ -0,0 +1,26 @@
"use strict";
var GrammarError = require("../../grammar-error"),
visitor = require("../visitor");
/* Checks that each rule is defined only once. */
function reportDuplicateRules(ast) {
var rules = {};
var check = visitor.build({
rule: function(node) {
if (rules.hasOwnProperty(node.name)) {
throw new GrammarError(
"Rule \"" + node.name + "\" is already defined.",
node.location
);
}
rules[node.name] = true;
}
});
check(ast);
}
module.exports = reportDuplicateRules;

@ -31,6 +31,7 @@
"lib/compiler/passes/report-left-recursion.js",
"lib/compiler/passes/report-infinite-loops.js",
"lib/compiler/passes/report-missing-rules.js",
"lib/compiler/passes/report-duplicate-rules.js",
"lib/grammar-error.js",
"lib/parser.js",
"lib/peg.js",

@ -10,6 +10,7 @@
<script src="unit/parser.spec.js"></script>
<script src="unit/compiler/passes/helpers.js"></script>
<script src="unit/compiler/passes/report-missing-rules.spec.js"></script>
<script src="unit/compiler/passes/report-duplicate-rules.spec.js"></script>
<script src="unit/compiler/passes/report-left-recursion.spec.js"></script>
<script src="unit/compiler/passes/report-infinite-loops.spec.js"></script>
<script src="unit/compiler/passes/remove-proxy-rules.spec.js"></script>

@ -0,0 +1,20 @@
/* global peg */
"use strict";
describe("compiler pass |reportDuplicateRules|", function() {
var pass = peg.compiler.passes.check.reportDuplicateRules;
it("reports duplicate rules", function() {
expect(pass).toReportError([
'start = "a"',
'start = "b"'
].join('\n'), {
message: 'Rule "start" is already defined.',
location: {
start: { offset: 12, line: 2, column: 1 },
end: { offset: 23, line: 2, column: 12 }
}
});
});
});
Loading…
Cancel
Save