pegjs/lib/compiler/asts.js
David Majda 0c39f1cf86 Fix labels leaking to outer scope
Labels in expressions like "(a:"a")" or "(a:"a" b:"b" c:"c")" were
visible to the outside despite being wrapped in parens. This commit
makes them invisible, as they should be.

Note this required introduction of a new "group" AST node, whose purpose
is purely to provide label scope isolation. This was necessary because
"label" and "sequence" nodes don't (and can't!) provide this isolation
themselves.

Part of a fix of #396.
2016-03-11 16:42:03 +01:00

66 lines
1.6 KiB
JavaScript

"use strict";
var arrays = require("../utils/arrays"),
visitor = require("./visitor");
/* AST utilities. */
var asts = {
findRule: function(ast, name) {
return arrays.find(ast.rules, function(r) { return r.name === name; });
},
indexOfRule: function(ast, name) {
return arrays.indexOf(ast.rules, function(r) { return r.name === name; });
},
alwaysConsumesOnSuccess: function(ast, node) {
function consumesTrue() { return true; }
function consumesFalse() { return false; }
function consumesExpression(node) {
return consumes(node.expression);
}
var consumes = visitor.build({
rule: consumesExpression,
named: consumesExpression,
choice: function(node) {
return arrays.every(node.alternatives, consumes);
},
action: consumesExpression,
sequence: function(node) {
return arrays.some(node.elements, consumes);
},
labeled: consumesExpression,
text: consumesExpression,
simple_and: consumesFalse,
simple_not: consumesFalse,
optional: consumesFalse,
zero_or_more: consumesFalse,
one_or_more: consumesExpression,
group: consumesExpression,
semantic_and: consumesFalse,
semantic_not: consumesFalse,
rule_ref: function(node) {
return consumes(asts.findRule(ast, node.name));
},
literal: function(node) {
return node.value !== "";
},
"class": consumesTrue,
any: consumesTrue
});
return consumes(node);
}
};
module.exports = asts;