Initial
This commit is contained in:
100
resources/app/node_modules/peggy/lib/compiler/visitor.js
generated
vendored
Normal file
100
resources/app/node_modules/peggy/lib/compiler/visitor.js
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
"use strict";
|
||||
|
||||
// Simple AST node visitor builder.
|
||||
const visitor = {
|
||||
build(functions) {
|
||||
function visit(node, ...args) {
|
||||
return functions[node.type](node, ...args);
|
||||
}
|
||||
|
||||
function visitNop() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
function visitExpression(node, ...args) {
|
||||
return visit(node.expression, ...args);
|
||||
}
|
||||
|
||||
function visitChildren(property) {
|
||||
return function(node, ...args) {
|
||||
// We do not use .map() here, because if you need the result
|
||||
// of applying visitor to children you probable also need to
|
||||
// process it in some way, therefore you anyway have to override
|
||||
// this method. If you do not needed that, we do not waste time
|
||||
// and memory for creating the output array
|
||||
node[property].forEach(child => visit(child, ...args));
|
||||
};
|
||||
}
|
||||
|
||||
const DEFAULT_FUNCTIONS = {
|
||||
grammar(node, ...args) {
|
||||
for (const imp of node.imports) {
|
||||
visit(imp, ...args);
|
||||
}
|
||||
|
||||
if (node.topLevelInitializer) {
|
||||
if (Array.isArray(node.topLevelInitializer)) {
|
||||
for (const tli of node.topLevelInitializer) {
|
||||
visit(tli, ...args);
|
||||
}
|
||||
} else {
|
||||
visit(node.topLevelInitializer, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
if (node.initializer) {
|
||||
if (Array.isArray(node.initializer)) {
|
||||
for (const init of node.initializer) {
|
||||
visit(init, ...args);
|
||||
}
|
||||
} else {
|
||||
visit(node.initializer, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
node.rules.forEach(rule => visit(rule, ...args));
|
||||
},
|
||||
|
||||
grammar_import: visitNop,
|
||||
top_level_initializer: visitNop,
|
||||
initializer: visitNop,
|
||||
rule: visitExpression,
|
||||
named: visitExpression,
|
||||
choice: visitChildren("alternatives"),
|
||||
action: visitExpression,
|
||||
sequence: visitChildren("elements"),
|
||||
labeled: visitExpression,
|
||||
text: visitExpression,
|
||||
simple_and: visitExpression,
|
||||
simple_not: visitExpression,
|
||||
optional: visitExpression,
|
||||
zero_or_more: visitExpression,
|
||||
one_or_more: visitExpression,
|
||||
repeated(node, ...args) {
|
||||
if (node.delimiter) {
|
||||
visit(node.delimiter, ...args);
|
||||
}
|
||||
|
||||
return visit(node.expression, ...args);
|
||||
},
|
||||
group: visitExpression,
|
||||
semantic_and: visitNop,
|
||||
semantic_not: visitNop,
|
||||
rule_ref: visitNop,
|
||||
library_ref: visitNop,
|
||||
literal: visitNop,
|
||||
class: visitNop,
|
||||
any: visitNop,
|
||||
};
|
||||
|
||||
Object.keys(DEFAULT_FUNCTIONS).forEach(type => {
|
||||
if (!Object.prototype.hasOwnProperty.call(functions, type)) {
|
||||
functions[type] = DEFAULT_FUNCTIONS[type];
|
||||
}
|
||||
});
|
||||
|
||||
return visit;
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = visitor;
|
||||
Reference in New Issue
Block a user