io.nosqlbench.virtdata.lang.parser.VirtDataBuilder Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2022 nosqlbench
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.nosqlbench.virtdata.lang.parser;
import io.nosqlbench.virtdata.lang.ast.*;
import io.nosqlbench.virtdata.lang.generated.VirtDataBaseListener;
import io.nosqlbench.virtdata.lang.generated.VirtDataParser;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import java.util.regex.Pattern;
public class VirtDataBuilder extends VirtDataBaseListener {
private final static Logger logger = LogManager.getLogger(VirtDataBuilder.class);
private final VirtDataAST model = new VirtDataAST();
private final List errorNodes = new ArrayList<>();
private final Stack flowContexts = new Stack<>();
private final Stack expressionContexts = new Stack<>();
private final Stack callContexts = new Stack<>();
private final LinkedList flows = new LinkedList<>();
private final Stack calls = new Stack();
@Override
public void enterVirtdataRecipe(VirtDataParser.VirtdataRecipeContext ctx) {
logger.trace("parsing virtdata lambda recipe.");
flowContexts.clear();
expressionContexts.clear();
callContexts.clear();
flows.clear();
}
@Override
public void exitVirtdataRecipe(VirtDataParser.VirtdataRecipeContext ctx) {
logger.trace("parsed virtdata recipe.");
}
@Override
public void enterVirtdataFlow(VirtDataParser.VirtdataFlowContext ctx) {
logger.trace("parsing virtdata flow...");
flowContexts.push(ctx);
flows.push(new VirtDataFlow());
calls.clear();
if (ctx.COMPOSE()!=null) {
logger.warn("The 'compose' keyword is no longer needed in lambda construction. It will be deprecated in the future.");
}
}
@Override
public void exitVirtdataFlow(VirtDataParser.VirtdataFlowContext ctx) {
model.addFlow(flows.pop());
flowContexts.pop();
}
@Override
public void enterExpression(VirtDataParser.ExpressionContext ctx) {
expressionContexts.push(ctx);
flows.peek().addExpression(new Expression());
}
@Override
public void exitLvalue(VirtDataParser.LvalueContext ctx) {
flows.peek().getLastExpression().setAssignment(new Assignment(ctx.ID().getSymbol().getText()));
}
@Override
public void exitExpression(VirtDataParser.ExpressionContext ctx) {
expressionContexts.pop();
}
@Override
public void enterVirtdataCall(VirtDataParser.VirtdataCallContext ctx) {
callContexts.push(ctx);
calls.push(new FunctionCall());
}
@Override
public void exitVirtdataCall(VirtDataParser.VirtdataCallContext ctx) {
FunctionCall topFunctionCall = calls.pop();
if (calls.empty()) {
flows.peek().getLastExpression().setCall(topFunctionCall);
} else {
calls.peek().addFunctionArg(topFunctionCall);
}
callContexts.pop();
}
@Override
public void exitInputType(VirtDataParser.InputTypeContext ctx) {
calls.peek().setInputType(ctx.getText());
}
@Override
public void exitFuncName(VirtDataParser.FuncNameContext ctx) {
calls.peek().setFuncName(ctx.getText());
}
@Override
public void exitOutputType(VirtDataParser.OutputTypeContext ctx) {
calls.peek().setOutputType(ctx.getText());
}
@Override
public void exitRef(VirtDataParser.RefContext ctx) {
calls.peek().addFunctionArg(new RefArg(ctx.ID().getText()));
}
@Override
public void exitIntegerValue(VirtDataParser.IntegerValueContext ctx) {
calls.peek().addFunctionArg(new IntegerArg(Integer.valueOf(ctx.getText())));
}
@Override
public void exitBooleanValue(VirtDataParser.BooleanValueContext ctx) {
calls.peek().addFunctionArg(new BooleanArg(Boolean.valueOf(ctx.getText())));
}
@Override
public void exitFloatValue(VirtDataParser.FloatValueContext ctx) {
calls.peek().addFunctionArg(new FloatArg(Float.valueOf(ctx.getText())));
}
private static final Pattern escapePattern = Pattern.compile("\\.");
@Override
public void exitStringValue(VirtDataParser.StringValueContext ctx) {
StringArg stringArg = new StringArg(ctx.getText());
calls.peek().addFunctionArg(stringArg);
}
@Override
public void exitDoubleValue(VirtDataParser.DoubleValueContext ctx) {
calls.peek().addFunctionArg(new DoubleArg(Double.valueOf(ctx.getText().substring(0,ctx.getText().length()-1))));
}
@Override
public void exitLongValue(VirtDataParser.LongValueContext ctx) {
calls.peek().addFunctionArg(new LongArg(Long.valueOf(ctx.getText().substring(0,ctx.getText().length()-1))));
}
@Override
public void visitTerminal(TerminalNode terminalNode) {
}
@Override
public void visitErrorNode(ErrorNode errorNode) {
super.visitErrorNode(errorNode);
errorNodes.add(errorNode);
}
@Override
public void enterEveryRule(ParserRuleContext parserRuleContext) {
}
@Override
public void exitEveryRule(ParserRuleContext parserRuleContext) {
}
public boolean hasErrors() {
return (errorNodes.size() > 0);
}
public List getErrorNodes() {
return errorNodes;
}
public FunctionCall getVirtdataCall() {
return calls.peek().getVirtdataCall(0);
}
public VirtDataAST getModel() {
return model;
}
}