refactored Trees to be a plain object to avoid "this" invocation

This commit is contained in:
Camilo Roca 2020-02-16 17:53:03 +01:00
parent af45a02d1e
commit 66c652142c
1 changed files with 124 additions and 127 deletions

View File

@ -11,132 +11,129 @@ const {RuleContext} = require('./../RuleContext');
const {ATN: {INVALID_ALT_NUMBER}} = require('./../atn/ATN');
/** A set of utility routines useful for all kinds of ANTLR trees. */
function Trees() {
const Trees = {
/**
* Print out a whole tree in LISP form. {@link //getNodeText} is used on the
* node payloads to get the text for the nodes. Detect
* parse trees and extract data appropriately.
*/
toStringTree: function(tree, ruleNames, recog) {
ruleNames = ruleNames || null;
recog = recog || null;
if(recog!==null) {
ruleNames = recog.ruleNames;
}
let s = Trees.getNodeText(tree, ruleNames);
s = Utils.escapeWhitespace(s, false);
const c = tree.getChildCount();
if(c===0) {
return s;
}
let res = "(" + s + ' ';
if(c>0) {
s = Trees.toStringTree(tree.getChild(0), ruleNames);
res = res.concat(s);
}
for(let i=1;i<c;i++) {
s = Trees.toStringTree(tree.getChild(i), ruleNames);
res = res.concat(' ' + s);
}
res = res.concat(")");
return res;
},
getNodeText: function(t, ruleNames, recog) {
ruleNames = ruleNames || null;
recog = recog || null;
if(recog!==null) {
ruleNames = recog.ruleNames;
}
if(ruleNames!==null) {
if (t instanceof RuleContext) {
const altNumber = t.getAltNumber();
if ( altNumber!=INVALID_ALT_NUMBER ) {
return ruleNames[t.ruleIndex]+":"+altNumber;
}
return ruleNames[t.ruleIndex];
} else if ( t instanceof ErrorNode) {
return t.toString();
} else if(t instanceof TerminalNode) {
if(t.symbol!==null) {
return t.symbol.text;
}
}
}
// no recog for rule names
const payload = t.getPayload();
if (payload instanceof Token ) {
return payload.text;
}
return t.getPayload().toString();
},
/**
* Return ordered list of all children of this node
*/
getChildren: function(t) {
const list = [];
for(let i=0;i<t.getChildCount();i++) {
list.push(t.getChild(i));
}
return list;
},
/**
* Return a list of all ancestors of this node. The first node of
* list is the root and the last is the parent of this node.
*/
getAncestors: function(t) {
let ancestors = [];
t = t.getParent();
while(t!==null) {
ancestors = [t].concat(ancestors);
t = t.getParent();
}
return ancestors;
},
findAllTokenNodes: function(t, ttype) {
return Trees.findAllNodes(t, ttype, true);
},
findAllRuleNodes: function(t, ruleIndex) {
return Trees.findAllNodes(t, ruleIndex, false);
},
findAllNodes: function(t, index, findTokens) {
const nodes = [];
Trees._findAllNodes(t, index, findTokens, nodes);
return nodes;
},
_findAllNodes: function(t, index, findTokens, nodes) {
// check this node (the root) first
if(findTokens && (t instanceof TerminalNode)) {
if(t.symbol.type===index) {
nodes.push(t);
}
} else if(!findTokens && (t instanceof ParserRuleContext)) {
if(t.ruleIndex===index) {
nodes.push(t);
}
}
// check children
for(let i=0;i<t.getChildCount();i++) {
Trees._findAllNodes(t.getChild(i), index, findTokens, nodes);
}
},
descendants: function(t) {
let nodes = [t];
for(let i=0;i<t.getChildCount();i++) {
nodes = nodes.concat(Trees.descendants(t.getChild(i)));
}
return nodes;
}
}
/**
* Print out a whole tree in LISP form. {@link //getNodeText} is used on the
* node payloads to get the text for the nodes. Detect
* parse trees and extract data appropriately.
*/
Trees.toStringTree = function(tree, ruleNames, recog) {
ruleNames = ruleNames || null;
recog = recog || null;
if(recog!==null) {
ruleNames = recog.ruleNames;
}
let s = Trees.getNodeText(tree, ruleNames);
s = Utils.escapeWhitespace(s, false);
const c = tree.getChildCount();
if(c===0) {
return s;
}
let res = "(" + s + ' ';
if(c>0) {
s = Trees.toStringTree(tree.getChild(0), ruleNames);
res = res.concat(s);
}
for(let i=1;i<c;i++) {
s = Trees.toStringTree(tree.getChild(i), ruleNames);
res = res.concat(' ' + s);
}
res = res.concat(")");
return res;
};
Trees.getNodeText = function(t, ruleNames, recog) {
ruleNames = ruleNames || null;
recog = recog || null;
if(recog!==null) {
ruleNames = recog.ruleNames;
}
if(ruleNames!==null) {
if (t instanceof RuleContext) {
const altNumber = t.getAltNumber();
if ( altNumber!=INVALID_ALT_NUMBER ) {
return ruleNames[t.ruleIndex]+":"+altNumber;
}
return ruleNames[t.ruleIndex];
} else if ( t instanceof ErrorNode) {
return t.toString();
} else if(t instanceof TerminalNode) {
if(t.symbol!==null) {
return t.symbol.text;
}
}
}
// no recog for rule names
const payload = t.getPayload();
if (payload instanceof Token ) {
return payload.text;
}
return t.getPayload().toString();
};
/**
* Return ordered list of all children of this node
*/
Trees.getChildren = function(t) {
const list = [];
for(let i=0;i<t.getChildCount();i++) {
list.push(t.getChild(i));
}
return list;
};
/**
* Return a list of all ancestors of this node. The first node of
* list is the root and the last is the parent of this node.
*/
Trees.getAncestors = function(t) {
let ancestors = [];
t = t.getParent();
while(t!==null) {
ancestors = [t].concat(ancestors);
t = t.getParent();
}
return ancestors;
};
Trees.findAllTokenNodes = function(t, ttype) {
return Trees.findAllNodes(t, ttype, true);
};
Trees.findAllRuleNodes = function(t, ruleIndex) {
return Trees.findAllNodes(t, ruleIndex, false);
};
Trees.findAllNodes = function(t, index, findTokens) {
const nodes = [];
Trees._findAllNodes(t, index, findTokens, nodes);
return nodes;
};
Trees._findAllNodes = function(t, index, findTokens, nodes) {
// check this node (the root) first
if(findTokens && (t instanceof TerminalNode)) {
if(t.symbol.type===index) {
nodes.push(t);
}
} else if(!findTokens && (t instanceof ParserRuleContext)) {
if(t.ruleIndex===index) {
nodes.push(t);
}
}
// check children
for(let i=0;i<t.getChildCount();i++) {
Trees._findAllNodes(t.getChild(i), index, findTokens, nodes);
}
};
Trees.descendants = function(t) {
let nodes = [t];
for(let i=0;i<t.getChildCount();i++) {
nodes = nodes.concat(Trees.descendants(t.getChild(i)));
}
return nodes;
};
exports.Trees = Trees;
module.exports = {Trees};