You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
2.3 KiB
JavaScript
98 lines
2.3 KiB
JavaScript
"use strict";
|
|
|
|
// Simple AST node visitor builder.
|
|
const visitor = {
|
|
build( functions ) {
|
|
|
|
function visit( node ) {
|
|
|
|
return functions[ node.type ].apply( null, arguments );
|
|
|
|
}
|
|
|
|
function visitNop() {
|
|
// Do nothing.
|
|
}
|
|
|
|
function visitExpression( node ) {
|
|
|
|
const extraArgs = Array.prototype.slice.call( arguments, 1 );
|
|
|
|
visit.apply( null, [ node.expression ].concat( extraArgs ) );
|
|
|
|
}
|
|
|
|
function visitChildren( property ) {
|
|
|
|
return function visitProperty( node ) {
|
|
|
|
const extraArgs = Array.prototype.slice.call( arguments, 1 );
|
|
|
|
node[ property ].forEach( child => {
|
|
|
|
visit.apply( null, [ child ].concat( extraArgs ) );
|
|
|
|
} );
|
|
|
|
};
|
|
|
|
}
|
|
|
|
const DEFAULT_FUNCTIONS = {
|
|
grammar( node ) {
|
|
|
|
const extraArgs = Array.prototype.slice.call( arguments, 1 );
|
|
|
|
if ( node.initializer ) {
|
|
|
|
visit.apply( null, [ node.initializer ].concat( extraArgs ) );
|
|
|
|
}
|
|
|
|
node.rules.forEach( rule => {
|
|
|
|
visit.apply( null, [ rule ].concat( extraArgs ) );
|
|
|
|
} );
|
|
|
|
},
|
|
|
|
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,
|
|
group: visitExpression,
|
|
semantic_and: visitNop,
|
|
semantic_not: visitNop,
|
|
rule_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;
|