package org.uva.ql.ast.builder;
import org.uva.ql.antlr.QLBaseVisitor;
import org.uva.ql.antlr.QLParser.BlockContext;
import org.uva.ql.antlr.QLParser.ExprAndContext;
import org.uva.ql.antlr.QLParser.ExprDivideContext;
import org.uva.ql.antlr.QLParser.ExprEqualContext;
import org.uva.ql.antlr.QLParser.ExprGreaterContext;
import org.uva.ql.antlr.QLParser.ExprGreaterEqualContext;
import org.uva.ql.antlr.QLParser.ExprLessContext;
import org.uva.ql.antlr.QLParser.ExprLessEqualContext;
import org.uva.ql.antlr.QLParser.ExprMinusContext;
import org.uva.ql.antlr.QLParser.ExprMultiplyContext;
import org.uva.ql.antlr.QLParser.ExprNegativeContext;
import org.uva.ql.antlr.QLParser.ExprNotContext;
import org.uva.ql.antlr.QLParser.ExprNotEqualContext;
import org.uva.ql.antlr.QLParser.ExprOrContext;
import org.uva.ql.antlr.QLParser.ExprParenthesesContext;
import org.uva.ql.antlr.QLParser.ExprPlusContext;
import org.uva.ql.antlr.QLParser.ExprPositiveContext;
import org.uva.ql.antlr.QLParser.FormContext;
import org.uva.ql.antlr.QLParser.IfContext;
import org.uva.ql.antlr.QLParser.IfElseContext;
import org.uva.ql.antlr.QLParser.LiteralBoolContext;
import org.uva.ql.antlr.QLParser.LiteralIdContext;
import org.uva.ql.antlr.QLParser.LiteralIntContext;
import org.uva.ql.antlr.QLParser.LiteralStrContext;
import org.uva.ql.antlr.QLParser.QuestionComputeContext;
import org.uva.ql.antlr.QLParser.QuestionIdentifierContext;
import org.uva.ql.antlr.QLParser.QuestionLabelContext;
import org.uva.ql.antlr.QLParser.QuestionNormalContext;
import org.uva.ql.antlr.QLParser.QuestionnaireContext;
import org.uva.ql.antlr.QLParser.StatementContext;
import org.uva.ql.antlr.QLParser.TypeBoolContext;
import org.uva.ql.antlr.QLParser.TypeIntContext;
import org.uva.ql.antlr.QLParser.TypeStrContext;
import org.uva.ql.ast.CodePosition;
import org.uva.ql.ast.Node;
import org.uva.ql.ast.expression.Expression;
import org.uva.ql.ast.expression.association.Parenthesis;
import org.uva.ql.ast.expression.binary.And;
import org.uva.ql.ast.expression.binary.Divide;
import org.uva.ql.ast.expression.binary.Equal;
import org.uva.ql.ast.expression.binary.Greater;
import org.uva.ql.ast.expression.binary.GreaterEqual;
import org.uva.ql.ast.expression.binary.Less;
import org.uva.ql.ast.expression.binary.LessEqual;
import org.uva.ql.ast.expression.binary.Substraction;
import org.uva.ql.ast.expression.binary.Multiply;
import org.uva.ql.ast.expression.binary.NotEqual;
import org.uva.ql.ast.expression.binary.Or;
import org.uva.ql.ast.expression.binary.Addition;
import org.uva.ql.ast.expression.literal.BoolLiteral;
import org.uva.ql.ast.expression.literal.Identifier;
import org.uva.ql.ast.expression.literal.IntLiteral;
import org.uva.ql.ast.expression.literal.StrLiteral;
import org.uva.ql.ast.expression.unary.Negative;
import org.uva.ql.ast.expression.unary.Not;
import org.uva.ql.ast.expression.unary.Positive;
import org.uva.ql.ast.questionnaire.Form;
import org.uva.ql.ast.questionnaire.Questionnaire;
import org.uva.ql.ast.statement.Block;
import org.uva.ql.ast.statement.IfElseStatement;
import org.uva.ql.ast.statement.IfStatement;
import org.uva.ql.ast.statement.QuestionComputed;
import org.uva.ql.ast.statement.QuestionNormal;
import org.uva.ql.ast.statement.Statement;
import org.uva.ql.ast.type.BoolType;
import org.uva.ql.ast.type.IntType;
import org.uva.ql.ast.type.StrType;
import org.uva.ql.ast.type.Type;
import org.uva.ql.ast.value.StrValue;
public class QLImplVisitor extends QLBaseVisitor<Node> {
private final String DOUBLE_QUOTE_ESCAPE_PATTERN = "^\"|\"$";
@Override
public Node visitQuestionnaire(QuestionnaireContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Questionnaire questionnaire = new Questionnaire(pos);
for (FormContext formContext : ctx.form()) {
questionnaire.addForm((Form) formContext.accept(this));
}
return questionnaire;
}
@Override
public Node visitForm(FormContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Identifier id = new Identifier(ctx.Identifier().getText(), pos);
Block block = (Block) ctx.block().accept(this);
return new Form(id, block, pos);
}
@Override
public Node visitBlock(BlockContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Block block = new Block(pos);
for (StatementContext statementContext : ctx.statement()) {
block.addStatement((Statement) statementContext.accept(this));
}
return block;
}
@Override
public Node visitIf(IfContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Expression expr = (Expression) ctx.expression().accept(this);
Block block = (Block) ctx.ifBody.accept(this);
return new IfStatement(expr, block, pos);
}
@Override
public Node visitIfElse(IfElseContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Expression expr = (Expression) ctx.expression().accept(this);
Block ifBlock = (Block) ctx.ifBody.accept(this);
Block elseBlock = (Block) ctx.elseBody.accept(this);
IfElseStatement ifElseStatement = new IfElseStatement(expr, ifBlock, elseBlock, pos);
return ifElseStatement;
}
@Override
public Node visitQuestionNormal(QuestionNormalContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Identifier id = (Identifier) ctx.questionIdentifier().accept(this);
StrLiteral label = (StrLiteral) ctx.questionLabel().accept(this);
Type type = (Type) ctx.questionType().accept(this);
return new QuestionNormal(id, label, type, pos);
}
@Override
public Node visitQuestionCompute(QuestionComputeContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Identifier id = (Identifier) ctx.questionIdentifier().accept(this);
StrLiteral label = (StrLiteral) ctx.questionLabel().accept(this);
Type type = (Type) ctx.questionType().accept(this);
Expression expr = (Expression) ctx.expression().accept(this);
return new QuestionComputed(id, label, type, expr, pos);
}
@Override
public Node visitTypeInt(TypeIntContext ctx) {
return new IntType(CodePosition.getCodePosition(ctx));
}
@Override
public Node visitTypeBool(TypeBoolContext ctx) {
return new BoolType(CodePosition.getCodePosition(ctx));
}
@Override
public Node visitTypeStr(TypeStrContext ctx) {
return new StrType(CodePosition.getCodePosition(ctx));
}
@Override
public Node visitExprNot(ExprNotContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Expression expr = (Expression) ctx.expression().accept(this);
return new Not(expr, pos);
}
@Override
public Node visitExprPositive(ExprPositiveContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Expression expr = (Expression) ctx.expression().accept(this);
return new Positive(expr, pos);
}
@Override
public Node visitExprNegative(ExprNegativeContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Expression expr = (Expression) ctx.expression().accept(this);
return new Negative(expr, pos);
}
@Override
public Node visitExprPlus(ExprPlusContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Expression left = (Expression) ctx.left.accept(this);
Expression right = (Expression) ctx.right.accept(this);
return new Addition(left, right, pos);
}
@Override
public Node visitExprMinus(ExprMinusContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Expression left = (Expression) ctx.left.accept(this);
Expression right = (Expression) ctx.right.accept(this);
return new Substraction(left, right, pos);
}
@Override
public Node visitExprMultiply(ExprMultiplyContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Expression left = (Expression) ctx.left.accept(this);
Expression right = (Expression) ctx.right.accept(this);
return new Multiply(left, right, pos);
}
@Override
public Node visitExprDivide(ExprDivideContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Expression left = (Expression) ctx.left.accept(this);
Expression right = (Expression) ctx.right.accept(this);
return new Divide(left, right, pos);
}
@Override
public Node visitExprAnd(ExprAndContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Expression left = (Expression) ctx.left.accept(this);
Expression right = (Expression) ctx.right.accept(this);
return new And(left, right, pos);
}
@Override
public Node visitExprOr(ExprOrContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Expression left = (Expression) ctx.left.accept(this);
Expression right = (Expression) ctx.right.accept(this);
return new Or(left, right, pos);
}
@Override
public Node visitExprEqual(ExprEqualContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Expression left = (Expression) ctx.left.accept(this);
Expression right = (Expression) ctx.right.accept(this);
return new Equal(left, right, pos);
}
@Override
public Node visitExprNotEqual(ExprNotEqualContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Expression left = (Expression) ctx.left.accept(this);
Expression right = (Expression) ctx.right.accept(this);
return new NotEqual(left, right, pos);
}
@Override
public Node visitExprGreater(ExprGreaterContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Expression left = (Expression) ctx.left.accept(this);
Expression right = (Expression) ctx.right.accept(this);
return new Greater(left, right, pos);
}
@Override
public Node visitExprGreaterEqual(ExprGreaterEqualContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Expression left = (Expression) ctx.left.accept(this);
Expression right = (Expression) ctx.right.accept(this);
return new GreaterEqual(left, right, pos);
}
@Override
public Node visitExprLess(ExprLessContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Expression left = (Expression) ctx.left.accept(this);
Expression right = (Expression) ctx.right.accept(this);
return new Less(left, right, pos);
}
@Override
public Node visitExprLessEqual(ExprLessEqualContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
Expression left = (Expression) ctx.left.accept(this);
Expression right = (Expression) ctx.right.accept(this);
return new LessEqual(left, right, pos);
}
@Override
public Node visitLiteralId(LiteralIdContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
return new Identifier(ctx.Identifier().getText(), pos);
}
@Override
public Node visitLiteralInt(LiteralIntContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
return new IntLiteral(Integer.parseInt(ctx.getText()), pos);
}
@Override
public Node visitLiteralStr(LiteralStrContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
return new StrLiteral(ctx.StringLiteral().getText().replaceAll(DOUBLE_QUOTE_ESCAPE_PATTERN, ""), pos);
}
@Override
public Node visitLiteralBool(LiteralBoolContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
return new BoolLiteral(Boolean.parseBoolean(ctx.getText()), pos);
}
@Override
public Node visitExprParentheses(ExprParenthesesContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
return new Parenthesis((Expression) ctx.expression().accept(this), pos);
}
@Override
public Node visitQuestionIdentifier(QuestionIdentifierContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
return new Identifier(ctx.Identifier().getText(), pos);
}
@Override
public Node visitQuestionLabel(QuestionLabelContext ctx) {
CodePosition pos = CodePosition.getCodePosition(ctx);
StrValue value = new StrValue(ctx.StringLiteral().getText().replaceAll(DOUBLE_QUOTE_ESCAPE_PATTERN, ""));
return new StrLiteral(value, pos);
}
}