Files
Foundry-VTT-Docker/resources/app/node_modules/peggy/lib/compiler/visitor.js

101 lines
2.7 KiB
JavaScript
Raw Normal View History

2025-01-04 00:34:03 +01:00
"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;