package edu.parser.QL; import com.sun.javaws.exceptions.InvalidArgumentException; import edu.exceptions.ParseException; import edu.gui.components.store.DefaultStore; import edu.nodes.QuestionType; import edu.parser.QL.antlrGenerated.QLBaseVisitor; import edu.parser.QL.antlrGenerated.QLParser; import edu.parser.QL.nodes.AbstractNode; import edu.parser.QL.nodes.Form; import edu.parser.QL.nodes.expression.*; import edu.parser.QL.nodes.question.Label; import edu.parser.QL.nodes.question.Question; import edu.parser.QL.nodes.statement.ElseClause; import edu.parser.QL.nodes.statement.IfStatement; import edu.parser.QL.nodes.statement.Statement; import edu.parser.QL.nodes.type.Boolean; import org.antlr.v4.runtime.misc.NotNull; import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; /** * Created by Steven Kok on 17/02/2015. */ public class ParseTreeVisitor extends QLBaseVisitor<AbstractNode> { @Override public AbstractNode visitBooleanExpression(@NotNull QLParser.BooleanExpressionContext ctx) { return new Boolean(ctx.isTrue != null); } @Override public AbstractNode visitGreaterOrEqual(@NotNull QLParser.GreaterOrEqualContext ctx) { return new GreaterOrEqual((Expression) ctx.left.accept(this), (Expression) ctx.right.accept(this)); } @Override public AbstractNode visitNumbersLabel(@NotNull QLParser.NumbersLabelContext ctx) { String number = ctx.numbers.getText(); return new edu.parser.QL.nodes.type.Number(Integer.parseInt(number)); } @Override public AbstractNode visitLessOrEqual(@NotNull QLParser.LessOrEqualContext ctx) { return new LessOrEqual((Expression) ctx.left.accept(this), (Expression) ctx.right.accept(this)); } @Override public AbstractNode visitSubtraction(@NotNull QLParser.SubtractionContext ctx) { return new Subtraction((Expression) ctx.left.accept(this), (Expression) ctx.right.accept(this)); } @Override public AbstractNode visitNotEqual(@NotNull QLParser.NotEqualContext ctx) { return new NotEqual((Expression) ctx.left.accept(this), (Expression) ctx.right.accept(this)); } @Override public AbstractNode visitDivision(@NotNull QLParser.DivisionContext ctx) { return new Division((Expression) ctx.left.accept(this), (Expression) ctx.right.accept(this)); } @Override public AbstractNode visitEqual(@NotNull QLParser.EqualContext ctx) { return new Equal((Expression) ctx.left.accept(this), (Expression) ctx.right.accept(this)); } @Override public AbstractNode visitLessThan(@NotNull QLParser.LessThanContext ctx) { return new LessThan((Expression) ctx.left.accept(this), (Expression) ctx.right.accept(this)); } @Override public AbstractNode visitMultiplication(@NotNull QLParser.MultiplicationContext ctx) { return new Multiplication((Expression) ctx.left.accept(this), (Expression) ctx.right.accept(this)); } @Override public AbstractNode visitAddition(@NotNull QLParser.AdditionContext ctx) { return new Addition((Expression) ctx.left.accept(this), (Expression) ctx.right.accept(this)); } @Override public AbstractNode visitGreaterThan(@NotNull QLParser.GreaterThanContext ctx) { return new GreaterThan((Expression) ctx.left.accept(this), (Expression) ctx.right.accept(this)); } @Override public AbstractNode visitNegationLabel(@NotNull QLParser.NegationLabelContext ctx) { Expression expression = (Expression) ctx.expression().accept(this); return new Not(expression); } @Override public AbstractNode visitOr(@NotNull QLParser.OrContext ctx) { return new Or((Expression) ctx.left.accept(this), (Expression) ctx.right.accept(this)); } @Override public AbstractNode visitAnd(@NotNull QLParser.AndContext ctx) { return new And((Expression) ctx.left.accept(this), (Expression) ctx.right.accept(this)); } @Override public AbstractNode visitIdentifierLabel(@NotNull QLParser.IdentifierLabelContext ctx) { return ctx.identifier().accept(this); } @Override public AbstractNode visitParenthesis(@NotNull QLParser.ParenthesisContext ctx) { return ctx.expression().accept(this); } @Override public AbstractNode visitBooleanExpressionLabel(@NotNull QLParser.BooleanExpressionLabelContext ctx) { return ctx.booleanExpression().accept(this); } @Override public Form visitForm(@NotNull QLParser.FormContext ctx) { List<Statement> statements = collectStatements(ctx.statement()); return new Form(statements); } @Override public AbstractNode visitQuestionLabel(@NotNull QLParser.QuestionLabelContext ctx) { return ctx.question().accept(this); } @Override public AbstractNode visitIf_statementLabel(@NotNull QLParser.If_statementLabelContext ctx) { return ctx.if_statement().accept(this); } @Override public AbstractNode visitIf_statement(@NotNull QLParser.If_statementContext ctx) { Expression expression = (Expression) visit(ctx.expression()); List<Statement> statements = collectStatements(ctx.statement()); Optional<ElseClause> elseClause = getElseClause(ctx); return new IfStatement(expression, statements, elseClause); } private Optional<ElseClause> getElseClause(QLParser.If_statementContext ctx) { if (ctx.else_clause() != null) { return Optional.of((ElseClause) visit(ctx.else_clause())); } else { return Optional.empty(); } } @Override public AbstractNode visitQuestion(@NotNull QLParser.QuestionContext ctx) { QuestionType questionType = (QuestionType) visit(ctx.question_type()); QLIdentifier QLIdentifier = (QLIdentifier) visit(ctx.identifier()); Label label = (Label) visit(ctx.question_label()); Optional<Expression> questionExpression = getQuestionExpression(ctx); boolean isQuestionEnabled = isQuestionEnabled(questionType); return new Question(QLIdentifier, questionType, label, isQuestionEnabled, questionExpression, Collections.emptyList(), new DefaultStore()); } private boolean isQuestionEnabled(QuestionType questionType) { return !questionType.equals(QuestionType.BOOLEAN); } private Optional<Expression> getQuestionExpression(QLParser.QuestionContext expressionContext) { if (expressionContext.question_expression() != null) { Expression expression = (Expression) expressionContext.question_expression().accept(this); return Optional.of(expression); } else { return Optional.empty(); } } @Override public AbstractNode visitQuestion_expression(@NotNull QLParser.Question_expressionContext ctx) { return ctx.expression().accept(this); } @Override public AbstractNode visitQuestion_label(@NotNull QLParser.Question_labelContext ctx) { return new Label(removeQuotesFromString(ctx.getText())); } private String removeQuotesFromString(String text) { return text.substring(1, text.length() - 1); } @Override public AbstractNode visitIdentifier(@NotNull QLParser.IdentifierContext ctx) { return new QLIdentifier(ctx.getText()); } @Override public AbstractNode visitQuestion_type(@NotNull QLParser.Question_typeContext ctx) { try { return QuestionType.getType(ctx.getText()); } catch (InvalidArgumentException e) { throw new ParseException("No question type found for: " + ctx.getText()); } } private List<Statement> collectStatements(List<QLParser.StatementContext> statementContexts) { return statementContexts .stream() .map(statementContext -> (Statement) visit(statementContext)) .collect(Collectors.toList()); } @Override public AbstractNode visitElse_clause(@NotNull QLParser.Else_clauseContext ctx) { List<Statement> statements = collectStatements(ctx.statement()); return new ElseClause(statements); } }