@gent-js/gent
Version:
template-based data generator.
60 lines (59 loc) • 2.25 kB
JavaScript
import { pickFirst } from "../../utils.js";
import { EXPRESSION_BLOCK_END, EXPRESSION_BLOCK_START } from "../consts.js";
import { lex, templateParser } from "./templateParser.js";
const emptyLiteralFragment = "";
const BaseVisitor = templateParser.getBaseCstVisitorConstructor();
class TemplateVisitor extends BaseVisitor {
constructor() {
super();
this.validateVisitor();
}
template(children, param) {
const templateFragmentNodes = children.templateFragment;
if (templateFragmentNodes === undefined) {
return [emptyLiteralFragment];
}
return templateFragmentNodes.flatMap((templateFragmentNode) => this.visit(templateFragmentNode));
}
templateFragment(children, param) {
const literalBlockCstNode = pickFirst(children.literalBlock);
const expressionBlockCstNode = pickFirst(children.expressionBlock);
if (literalBlockCstNode !== undefined) {
return this.visit(literalBlockCstNode);
}
else if (expressionBlockCstNode !== undefined) {
return this.visit(expressionBlockCstNode);
}
else {
return [];
}
}
literalBlock(children, param) {
const literalBlockToken = pickFirst(children.LiteralBlock);
if (literalBlockToken === undefined) {
return [];
}
return literalBlockToken.image;
}
expressionBlock(children, param) {
const expressionBlockToken = pickFirst(children.ExpressionBlock);
if (expressionBlockToken === undefined) {
return [];
}
const expressionBlock = expressionBlockToken.image;
const expression = expressionBlock.substring(EXPRESSION_BLOCK_START.length, expressionBlock.length - EXPRESSION_BLOCK_END.length);
return {
expression: expression,
};
}
}
const visitor = new TemplateVisitor();
export function toAstVisitor(input) {
const lexResult = lex(input);
templateParser.input = lexResult.tokens;
const cst = templateParser.template();
if (templateParser.errors.length > 0) {
throw Error("parsing errors detected!\n" + templateParser.errors[0]?.message);
}
return visitor.visit(cst);
}