This code defines four functions for working with Abstract Syntax Trees (ASTs) generated by the ANTLR4TS parser generator, including functions for converting object types to strings, creating generic tokens and contexts, and generating generic visitors. The code exports a module containing a generic visitor function.
npm run import -- "antlr tree visitor"
var {Interval} = require('antlr4ts/misc')
function typeToString(node) {
if(node === 'object' && node) {
return Object.getPrototypeOf(node).constructor.name;
} else {
return typeof node;
}
}
function getGenericToken(parser, token) {
if(!token) return
return {
type: 'TerminalNode',
// type2: parser.ruleNames[child._stop._type],
value: token.source.stream.getText(Interval.of(token.start, token.stop)),
range: [token.start, token.stop]
}
}
function getGenericContext(ctx) {
var exclude = [
'constructor',
'ruleIndex',
'enterRule',
'exitRule',
'accept'
]
var allTokens = Object.getOwnPropertyNames(Object.getPrototypeOf(ctx))
.filter(t => exclude.indexOf(t) === -1)
return allTokens.reduce((obj, cur) => {
obj[cur] = ctx[cur]()
return obj
}, {})
}
function getGenericVisitor({parser, visitor}) {
function GenericVisitor() {
// visitor.apply(this, arguments)
}
GenericVisitor.prototype = Object.create(visitor.prototype)
GenericVisitor.prototype.constructor = GenericVisitor
GenericVisitor.prototype.defaultResult = function () {
return {children: []}
}
GenericVisitor.prototype.aggregateResult = (ctx, child) => {
if(!Array.isArray(ctx)) ctx = ctx.children
ctx[ctx.length] = child
return ctx
}
GenericVisitor.prototype.visit = function (tree) {
return tree.accept(this)
}
// TODO: combine range with return valuess
GenericVisitor.prototype.visitTerminal = function (node) {
return getGenericToken(parser, node._symbol)
}
GenericVisitor.prototype.visitChildren = function (ctx) {
var result = visitor.prototype.visitChildren.apply(this, [ctx])
return {
type: Object.getPrototypeOf(ctx).constructor.name,
children: result
}
}
return {
GenericVisitor
}
}
module.exports = getGenericVisitor
const { Interval } = require('antlr4ts/misc');
/**
* Returns the string representation of the provided node type.
* If the node is an object, it returns the constructor name of the object's prototype.
* Otherwise, it returns the type of the node.
*
* @param {object|string} node - The node to get the type string for.
* @returns {string} The type string of the node.
*/
function typeToString(node) {
return Object.prototype.toString.call(node).replace(/\[object\s/, '').replace(/\]/, '');
}
/**
* Returns a generic token object from the provided parser and token.
* If the token is null or undefined, it returns null.
*
* @param {object} parser - The parser to get the token from.
* @param {object} token - The token to get the generic token object for.
* @returns {object|null} The generic token object, or null if the token is null or undefined.
*/
function getGenericToken(parser, token) {
if (!token) return null;
return {
type: 'TerminalNode',
value: token.source.stream.getText(Interval.of(token.start, token.stop)),
range: [token.start, token.stop]
};
}
/**
* Returns a generic context object from the provided context.
* The generic context object includes all properties of the context that are not excluded.
*
* @param {object} ctx - The context to get the generic context object for.
* @returns {object} The generic context object.
*/
function getGenericContext(ctx) {
const exclude = [
'constructor',
'ruleIndex',
'enterRule',
'exitRule',
'accept'
];
return Object.getOwnPropertyNames(Object.getPrototypeOf(ctx))
.filter((property) => exclude.indexOf(property) === -1)
.reduce((obj, property) => {
obj[property] = ctx[property] && typeof ctx[property] === 'function'? ctx[property]() : ctx[property];
return obj;
}, {});
}
/**
* Returns a generic visitor object from the provided parser and visitor.
* The generic visitor object includes a visit method that calls the accept method on the provided tree,
* and a visitTerminal method that returns a generic token object.
*
* @param {object} options - The options object with parser and visitor properties.
* @param {object} options.parser - The parser to get the generic token object from.
* @param {object} options.visitor - The visitor to create a generic visitor from.
* @returns {object} The generic visitor object.
*/
function getGenericVisitor({ parser, visitor }) {
class GenericVisitor extends visitor.constructor {
constructor(...args) {
super(...args);
}
defaultResult() {
return { children: [] };
}
aggregateResult(ctx, child) {
if (!Array.isArray(ctx)) ctx = ctx.children;
ctx.push(child);
return ctx;
}
visit(tree) {
return tree.accept(this);
}
visitTerminal(node) {
return getGenericToken(parser, node._symbol);
}
visitChildren(ctx) {
const result = visitor.constructor.prototype.visitChildren.apply(this, [ctx]);
return {
type: Object.prototype.toString.call(ctx).replace(/\[object\s/, '').replace(/\]/, ''),
children: result
};
}
}
return { GenericVisitor };
}
module.exports = getGenericVisitor;
Overview
This code defines several functions for working with Abstract Syntax Trees (ASTs) generated by the ANTLR4TS parser generator.
typeToString
This function takes an object as input and returns its type as a string. If the input is an object, it returns the name of the constructor it inherits from. Otherwise, it returns the type of the input using typeof
.
getGenericToken
This function takes a parser and a token as input and returns a generic token object. If the token is null or undefined, it returns null. Otherwise, it returns an object with the following properties:
type
: set to 'TerminalNode'
value
: the text of the token's source stream, extracted using ANTLR4TS.misc.Interval
range
: an array representing the start and stop positions of the tokengetGenericContext
This function takes a context object as input and returns an object with all its properties. It excludes certain properties (e.g., constructor
, ruleIndex
) from the output.
getGenericVisitor
This function takes an object with parser
and visitor
properties as input and returns a generic visitor object. The visitor object has several methods:
defaultResult
: returns an object with an empty array as its children
propertyaggregateResult
: appends a child node to the children
array of the current contextvisit
: calls the accept
method on the current tree with the visitor as an argumentvisitTerminal
: calls getGenericToken
to get the token object for a terminal nodevisitChildren
: calls the visitChildren
method on the visitor's prototype
and returns an object with the type of the current context and its childrenThe getGenericVisitor
function returns an object with the generic visitor as its only property.
The code exports the getGenericVisitor
function as a module.