antlr-ng
Version:
Next generation ANTLR Tool
107 lines (106 loc) • 3.2 kB
JavaScript
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
class RewriteRuleElementStream {
static {
__name(this, "RewriteRuleElementStream");
}
/**
* Cursor 0..n-1. If singleElement!=null, cursor is 0 until you next(), which bumps it to 1 meaning no more
* elements.
*/
cursor = 0;
/** The list of tokens or subtrees we are tracking */
elements;
/**
* Once a node / subtree has been used in a stream, it must be dup'd from then on. Streams are reset after
* subrules so that the streams can be reused in future subrules. So, reset must set a dirty bit. If dirty,
* then next() always returns a dup.
*
* I wanted to use "naughty bit" here, but couldn't think of a way to use "naughty".
*/
dirty = false;
/**
* The element or stream description; usually has name of the token or rule reference that this list tracks. Can
* include rule name too, but the exception would track that info.
*/
elementDescription;
constructor(elementDescription, elements) {
this.elementDescription = elementDescription;
this.elements = elements ?? [];
}
/**
* Reset the condition of this stream so that it appears we have not consumed any of its elements. Elements
* themselves are untouched. Once we reset the stream, any future use will need duplicates. Set the dirty bit.
*/
reset() {
this.cursor = 0;
this.dirty = true;
}
add(el) {
if (el) {
this.elements.push(el);
}
}
/**
* Return the next element in the stream. If out of elements, throw an exception unless size() == 1. If size is 1,
* then return elements[0].
*
* @returns a duplicate node/subtree if stream is out of elements and size == 1. If we've already used the element,
* dup (dirty bit set).
*/
nextTree() {
const n = this.size();
if (this.dirty || this.cursor >= n && n === 1) {
const el = this.getNext();
return this.dup(el);
}
return this.getNext();
}
hasNext() {
return this.cursor < this.elements.length;
}
size() {
return this.elements.length;
}
getDescription() {
return this.elementDescription;
}
/**
* Does the work of getting the next element, making sure that it's a tree node or subtree. Throws an exception
* if the stream is empty or we're out of elements and size > 1.
*
* @returns the next element in the stream.
*/
getNext() {
const n = this.size();
if (n === 0) {
throw new Error(this.elementDescription);
}
if (this.cursor >= n) {
if (n === 1) {
return this.toTree(this.elements[0]);
}
throw new Error(this.elementDescription);
}
if (n === 1) {
this.cursor++;
return this.toTree(this.elements[0]);
}
const o = this.toTree(this.elements[this.cursor]);
this.cursor++;
return o;
}
/**
* Ensures stream emits trees. Tokens must be converted to AST nodes. AST nodes can be passed through unmolested.
*
* @param el The element to convert.
*
* @returns the element unaltered.
*/
toTree(el) {
return el;
}
}
export {
RewriteRuleElementStream
};