package org.fugazi.ql.ast;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.misc.NotNull;
import org.fugazi.ql.ast.expression.Expression;
import org.fugazi.ql.ast.expression.comparison.*;
import org.fugazi.ql.ast.expression.literal.BOOL;
import org.fugazi.ql.ast.expression.literal.ID;
import org.fugazi.ql.ast.expression.literal.INT;
import org.fugazi.ql.ast.expression.literal.STRING;
import org.fugazi.ql.ast.expression.logical.And;
import org.fugazi.ql.ast.expression.logical.Logical;
import org.fugazi.ql.ast.expression.logical.Or;
import org.fugazi.ql.ast.expression.numerical.*;
import org.fugazi.ql.ast.expression.unary.Negative;
import org.fugazi.ql.ast.expression.unary.Not;
import org.fugazi.ql.ast.expression.unary.Positive;
import org.fugazi.ql.ast.expression.unary.Unary;
import org.fugazi.ql.ast.form.Form;
import org.fugazi.ql.ast.statement.ComputedQuestion;
import org.fugazi.ql.ast.statement.IfStatement;
import org.fugazi.ql.ast.statement.Question;
import org.fugazi.ql.ast.statement.Statement;
import org.fugazi.ql.ast.type.BoolType;
import org.fugazi.ql.ast.type.IntType;
import org.fugazi.ql.ast.type.StringType;
import org.fugazi.ql.ast.type.Type;
import org.fugazi.ql.parser.QLBaseVisitor;
import org.fugazi.ql.parser.QLParser;
import java.util.ArrayList;
import java.util.List;
public class FugaziQLVisitor extends QLBaseVisitor<AbstractASTNode> {
private String removeStringQuotes(String _str) {
return _str.replaceAll("^\"|\"$", "");
}
private int getLineNumber(ParserRuleContext ctx) {
return ctx.getStart().getLine();
}
/**
* =======================
* form
* =======================
*/
@Override
public Form visitForm(@NotNull QLParser.FormContext ctx) {
String formName = ctx.ID().getText();
List<Statement> formStatements = new ArrayList<>();
for (QLParser.StatementContext statement : ctx.statement()) {
Statement stat = (Statement) statement.accept(this);
formStatements.add(stat);
}
Form form = new Form(formName, formStatements);
form.setLineNumber(this.getLineNumber(ctx));
return form;
}
/**
* =======================
* Statements
* =======================
*/
@Override
public IfStatement visitIfStatement(@NotNull QLParser.IfStatementContext ctx) {
Expression condition = (Expression) ctx.expression().accept(this);
List<Statement> statements = new ArrayList<>();
for (QLParser.StatementContext statement : ctx.statement()) {
Statement stat = (Statement) statement.accept(this);
statements.add(stat);
}
IfStatement ifStatement = new IfStatement(condition, statements);
ifStatement.setLineNumber( this.getLineNumber(ctx));
return ifStatement;
}
@Override
public Question visitSimpleQuestion(@NotNull QLParser.SimpleQuestionContext ctx) {
Type type = (Type) ctx.type().accept(this);
ID identifier = new ID(ctx.ID().getText());
identifier.setLineNumber(this.getLineNumber(ctx));
STRING grammarLabel = new STRING(ctx.STRING().getText());
grammarLabel.setLineNumber(this.getLineNumber(ctx));
String label = removeStringQuotes(grammarLabel.toString());
Question question = new Question(type, label, identifier);
question.setLineNumber(this.getLineNumber(ctx));
return question;
}
@Override
public ComputedQuestion visitComputedQuestion(@NotNull QLParser.ComputedQuestionContext ctx) {
Type type = (Type) ctx.type().accept(this);
ID identifier = new ID(ctx.ID().getText());
identifier.setLineNumber(this.getLineNumber(ctx));
STRING grammarLabel = new STRING(ctx.STRING().getText());
grammarLabel.setLineNumber(this.getLineNumber(ctx));
String label = removeStringQuotes(grammarLabel.toString());
Expression expression = (Expression) ctx.expression().accept(this);
ComputedQuestion question = new ComputedQuestion(type, label, identifier, expression);
question.setLineNumber(this.getLineNumber(ctx));
return question;
}
/**
* =======================
* Types
* =======================
*/
@Override
public BoolType visitBoolType(@NotNull QLParser.BoolTypeContext ctx) {
BoolType type = new BoolType();
type.setLineNumber(this.getLineNumber(ctx));
return type;
}
@Override
public IntType visitIntType(@NotNull QLParser.IntTypeContext ctx) {
IntType type = new IntType();
type.setLineNumber(this.getLineNumber(ctx));
return type;
}
@Override
public StringType visitStringType(@NotNull QLParser.StringTypeContext ctx) {
StringType type = new StringType();
type.setLineNumber(this.getLineNumber(ctx));
return type;
}
/**
* =======================
* Expressions
* =======================
*/
@Override
public Expression visitParenthesisExpression(@NotNull QLParser.ParenthesisExpressionContext ctx) {
return (Expression) ctx.expression().accept(this);
}
@Override
public Unary visitUnaryExpression(@NotNull QLParser.UnaryExpressionContext ctx) {
Expression expr = (Expression) ctx.expression().accept(this);
if (ctx.op.getText().equals("!")) {
Not expression = new Not(expr);
expression.setLineNumber(this.getLineNumber(ctx));
return expression;
}
if (ctx.op.getText().equals("-")) {
Negative expression = new Negative(expr);
expression.setLineNumber(this.getLineNumber(ctx));
return expression;
}
if (ctx.op.getText().equals("+")) {
Positive expression = new Positive(expr);
expression.setLineNumber(this.getLineNumber(ctx));
return expression;
}
return null;
}
@Override
public Numerical visitMulDivExpression(@NotNull QLParser.MulDivExpressionContext ctx) {
Expression leftExpr = (Expression) ctx.expression(0).accept(this);
Expression rightExpr = (Expression) ctx.expression(1).accept(this);
if (ctx.op.getText().equals("*")) {
Mul expression = new Mul(leftExpr, rightExpr);
expression.setLineNumber(this.getLineNumber(ctx));
return expression;
}
if (ctx.op.getText().equals("/")) {
Div expression = new Div(leftExpr, rightExpr);
expression.setLineNumber(this.getLineNumber(ctx));
return expression;
}
return null;
}
@Override
public Numerical visitAddSubExpression(@NotNull QLParser.AddSubExpressionContext ctx) {
Expression leftExpr = (Expression) ctx.expression().get(0).accept(this);
Expression rightExpr = (Expression) ctx.expression().get(1).accept(this);
if (ctx.op.getText().equals("+")) {
Add expression = new Add(leftExpr, rightExpr);
expression.setLineNumber(this.getLineNumber(ctx));
return expression;
}
if (ctx.op.getText().equals("-")) {
Sub expression = new Sub(leftExpr, rightExpr);
expression.setLineNumber(this.getLineNumber(ctx));
return expression;
}
return null;
}
@Override
public Logical visitLogicalOrExpression(@NotNull QLParser.LogicalOrExpressionContext ctx) {
Expression leftExpr = (Expression) ctx.expression().get(0).accept(this);
Expression rightExpr = (Expression) ctx.expression().get(1).accept(this);
Or expression = new Or(leftExpr, rightExpr);
expression.setLineNumber(this.getLineNumber(ctx));
return expression;
}
@Override
public Logical visitLogicalAndExpression(@NotNull QLParser.LogicalAndExpressionContext ctx) {
Expression leftExpr = (Expression) ctx.expression().get(0).accept(this);
Expression rightExpr = (Expression) ctx.expression().get(1).accept(this);
And expression = new And(leftExpr, rightExpr);
expression.setLineNumber(this.getLineNumber(ctx));
return expression;
}
@Override
public Comparison visitComparisonExpression(@NotNull QLParser.ComparisonExpressionContext ctx) {
Expression leftExpr = (Expression) ctx.expression().get(0).accept(this);
Expression rightExpr = (Expression) ctx.expression().get(1).accept(this);
if (ctx.op.getText().equals(">")) {
Greater expression = new Greater(leftExpr, rightExpr);
expression.setLineNumber(this.getLineNumber(ctx));
return expression;
}
if (ctx.op.getText().equals(">=")) {
GE expression = new GE(leftExpr, rightExpr);
expression.setLineNumber(this.getLineNumber(ctx));
return expression;
}
if (ctx.op.getText().equals("<")) {
Less expression = new Less(leftExpr, rightExpr);
expression.setLineNumber(this.getLineNumber(ctx));
return expression;
}
if (ctx.op.getText().equals("<=")) {
LE expression = new LE(leftExpr, rightExpr);
expression.setLineNumber(this.getLineNumber(ctx));
return expression;
}
if (ctx.op.getText().equals("==")) {
EQ expression = new EQ(leftExpr, rightExpr);
expression.setLineNumber(this.getLineNumber(ctx));
return expression;
}
if (ctx.op.getText().equals("!=")) {
NotEq expression = new NotEq(leftExpr, rightExpr);
expression.setLineNumber(this.getLineNumber(ctx));
return expression;
}
return null;
}
/**
* =======================
* literals
* =======================
*/
@Override
public INT visitIntExpression(@NotNull QLParser.IntExpressionContext ctx) {
int value = Integer.parseInt(ctx.INT().getText());
INT expression = new INT(value);
expression.setLineNumber(this.getLineNumber(ctx));
return expression;
}
@Override
public BOOL visitBoolExpression(@NotNull QLParser.BoolExpressionContext ctx) {
Boolean value = Boolean.parseBoolean(ctx.BOOL().getText());
BOOL expression = new BOOL(value);
expression.setLineNumber(this.getLineNumber(ctx));
return expression;
}
@Override
public ID visitIdentifierExpression(@NotNull QLParser.IdentifierExpressionContext ctx) {
String name = ctx.ID().getText();
ID identifier = new ID(name);
identifier.setLineNumber(this.getLineNumber(ctx));
return identifier;
}
@Override
public STRING visitStringExpression(@NotNull QLParser.StringExpressionContext ctx) {
String value = ctx.STRING().getText();
STRING expression = new STRING(value);
expression.setLineNumber(this.getLineNumber(ctx));
return expression;
}
}