Java tutorial
/******************************************************************************* * Copyright (c) 2015 Gary F. Pollice * * All rights reserved. This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Used in CS4533/CS544 at Worcester Polytechnic Institute *******************************************************************************/ package dijkstra.utility; import static dijkstra.lexparse.DijkstraParser.ID; import static dijkstra.lexparse.DijkstraParser.INTEGER; import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.Recognizer; import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.ErrorNode; import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.TerminalNode; import dijkstra.lexparse.DijkstraBaseListener; import dijkstra.lexparse.DijkstraParser; import dijkstra.lexparse.DijkstraParser.ArrayAccessorContext; import dijkstra.lexparse.DijkstraParser.ArrayDeclarationContext; import dijkstra.lexparse.DijkstraParser.CallContext; import dijkstra.lexparse.DijkstraParser.CompoundBodyContext; import dijkstra.lexparse.DijkstraParser.FunctionDeclarationContext; import dijkstra.lexparse.DijkstraParser.ParamContext; import dijkstra.lexparse.DijkstraParser.ProcedureDeclarationContext; import dijkstra.lexparse.DijkstraParser.ProgramContext; import dijkstra.lexparse.DijkstraParser.ReturnStatementContext; import dijkstra.lexparse.DijkstraParser.VariableContext; import dijkstra.lexparse.DijkstraParser.VariableDeclarationContext; /** * Example listener for the Toy Dijkstra grammar. This prints out a nicer trace than using * setTrace() on the parser. * * @version Feb 5, 2015 */ public class DijkstraTraceListener extends DijkstraBaseListener { private final Recognizer parser; private final String indent = " "; private final StringBuilder stringBuilder = new StringBuilder(); private int indentLevel; public DijkstraTraceListener(Recognizer parser) { super(); this.parser = parser; indentLevel = 0; } /** * {@inheritDoc} * * <p> * IF guard+ FI * </p> */ @Override public void enterAlternativeStatement(DijkstraParser.AlternativeStatementContext ctx) { stringBuilder.append(indent() + ctx.getChild(0).getText() + "\n"); indentLevel++; } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void enterArrayAccessor(ArrayAccessorContext ctx) { super.enterArrayAccessor(ctx); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void enterArrayDeclaration(ArrayDeclarationContext ctx) { super.enterArrayDeclaration(ctx); } /** * {@inheritDoc} * * <p> * ID ASSIGN expression SEMICOLON? * </p> */ @Override public void enterAssignStatement(DijkstraParser.AssignStatementContext ctx) { stringBuilder.append(indent() + tokenString(ctx.getChild(1)) + "\n"); indentLevel++; } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void enterCompoundBody(CompoundBodyContext ctx) { super.enterCompoundBody(ctx); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void enterCompoundStatement(DijkstraParser.CompoundStatementContext ctx) { stringBuilder.append(indent() + "{ }" + "\n"); indentLevel++; } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void enterDeclaration(DijkstraParser.DeclarationContext ctx) { stringBuilder.append(ruleName(ctx) + "\n"); // indentLevel++; // doPrint(ruleName(ctx) + " " + ctx.type().getText() + " '" // + ctx.ID().getText() + "'"); } @Override public void enterDijkstraText(DijkstraParser.DijkstraTextContext ctx) { } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void enterEveryRule(ParserRuleContext ctx) { } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void enterExpression(DijkstraParser.ExpressionContext ctx) { StringBuilder sb = new StringBuilder(); sb.append(ruleName(ctx) + " "); switch (ctx.getChildCount()) { case 1: // terminal node case 2: // unaryOperator expression sb.append(tokenString(ctx.getChild(0))); break; case 3: // Binary operator or parenthesized expression if (ctx.getChild(0) instanceof TerminalNode) { sb.append(" ()"); } else { sb.append(tokenString(ctx.getChild(1))); } } stringBuilder.append(indent() + sb.toString() + "\n"); indentLevel++; } // /** // * {@inheritDoc} // * // * <p> // * The default implementation does nothing. // * </p> // */ // @Override // public void enterFunctionCall(FunctionCallContext ctx) { // super.enterFunctionCall(ctx); // } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void enterFunctionDeclaration(FunctionDeclarationContext ctx) { super.enterFunctionDeclaration(ctx); } /** * {@inheritDoc} * * <p> * expression GUARD statement * </p> */ @Override public void enterGuard(DijkstraParser.GuardContext ctx) { stringBuilder.append(indent() + tokenString(ctx.getChild(1)) + "\n"); indentLevel++; } /** * {@inheritDoc} * * <p> * INPUT ID SEMICOLON? * </p> */ @Override public void enterInputStatement(DijkstraParser.InputStatementContext ctx) { stringBuilder.append(indent() + ctx.getChild(0).getText() + " " + tokenString(ctx.getChild(1)) + "\n"); } /** * {@inheritDoc} * * <p> * LOOP expression statement ; * </p> */ @Override public void enterIterativeStatement(DijkstraParser.IterativeStatementContext ctx) { stringBuilder.append(indent() + ctx.getChild(0).getText() + "\n"); indentLevel++; } /** * {@inheritDoc} * * <p> * PRINT expression SEMICOLON? * </p> */ @Override public void enterOutputStatement(DijkstraParser.OutputStatementContext ctx) { stringBuilder.append(indent() + ctx.getChild(0).getText() + "\n"); indentLevel++; } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void enterParam(ParamContext ctx) { super.enterParam(ctx); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ // @Override // public void enterPctExpr(PctExprContext ctx) { // super.enterPctExpr(ctx); // } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void enterCall(CallContext ctx) { super.enterCall(ctx); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void enterProcedureDeclaration(ProcedureDeclarationContext ctx) { super.enterProcedureDeclaration(ctx); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void enterProgram(DijkstraParser.ProgramContext ctx) { stringBuilder.append(ruleName(ctx) + " '" + ctx.ID().getText() + "'" + "\n"); indentLevel++; } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void enterReturnStatement(ReturnStatementContext ctx) { super.enterReturnStatement(ctx); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void enterStatement(DijkstraParser.StatementContext ctx) { stringBuilder.append(ruleName(ctx) + "\n"); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void enterType(DijkstraParser.TypeContext ctx) { } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void enterVariable(VariableContext ctx) { super.enterVariable(ctx); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void enterVariableDeclaration(VariableDeclarationContext ctx) { stringBuilder.append(indent() + ruleName(ctx) + " " + tokenString(ctx.type().getChild(0))); for (TerminalNode id : ctx.ID()) { stringBuilder.append(" " + id); } stringBuilder.append("\n"); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitAlternativeStatement(DijkstraParser.AlternativeStatementContext ctx) { indentLevel--; stringBuilder.append(indent() + ctx.getChild(ctx.getChildCount() - 1).getText() + "\n"); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitArrayAccessor(ArrayAccessorContext ctx) { super.exitArrayAccessor(ctx); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitArrayDeclaration(ArrayDeclarationContext ctx) { super.exitArrayDeclaration(ctx); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitAssignStatement(DijkstraParser.AssignStatementContext ctx) { indentLevel--; } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitCompoundBody(CompoundBodyContext ctx) { super.exitCompoundBody(ctx); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitCompoundStatement(DijkstraParser.CompoundStatementContext ctx) { indentLevel--; } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitDeclaration(DijkstraParser.DeclarationContext ctx) { // indentLevel--; } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitDijkstraText(DijkstraParser.DijkstraTextContext ctx) { } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitEveryRule(ParserRuleContext ctx) { } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitExpression(DijkstraParser.ExpressionContext ctx) { indentLevel--; } // /** // * {@inheritDoc} // * // * <p> // * The default implementation does nothing. // * </p> // */ // @Override // public void exitFunctionCall(FunctionCallContext ctx) { // super.exitFunctionCall(ctx); // } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitFunctionDeclaration(FunctionDeclarationContext ctx) { super.exitFunctionDeclaration(ctx); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitGuard(DijkstraParser.GuardContext ctx) { indentLevel--; } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitInputStatement(DijkstraParser.InputStatementContext ctx) { } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitIterativeStatement(DijkstraParser.IterativeStatementContext ctx) { indentLevel--; } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitOutputStatement(DijkstraParser.OutputStatementContext ctx) { indentLevel--; } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitParam(ParamContext ctx) { super.exitParam(ctx); } // /** // * {@inheritDoc} // * // * <p> // * The default implementation does nothing. // * </p> // */ // @Override // public void exitPctExpr(PctExprContext ctx) { // super.exitPctExpr(ctx); // } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitCall(CallContext ctx) { super.exitCall(ctx); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitProcedureDeclaration(ProcedureDeclarationContext ctx) { super.exitProcedureDeclaration(ctx); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitProgram(ProgramContext ctx) { super.exitProgram(ctx); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitReturnStatement(ReturnStatementContext ctx) { super.exitReturnStatement(ctx); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitStatement(DijkstraParser.StatementContext ctx) { } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitType(DijkstraParser.TypeContext ctx) { } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitVariable(VariableContext ctx) { super.exitVariable(ctx); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void exitVariableDeclaration(VariableDeclarationContext ctx) { super.exitVariableDeclaration(ctx); } private String indent() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < indentLevel; i++) { sb.append(indent); } return sb.toString(); } private String ruleName(ParserRuleContext ctx) { return "[" + parser.getRuleNames()[ctx.getRuleIndex()] + "]"; } private String tokenString(ParseTree pt) { StringBuilder sb = new StringBuilder(); Token t = ((TerminalNode) pt).getSymbol(); if (t.getType() == INTEGER | t.getType() == ID) { sb.append(parser.getVocabulary().getDisplayName(t.getType()) + " '" + t.getText() + "'"); } else { sb.append(parser.getVocabulary().getDisplayName(t.getType())); } return sb.toString(); } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void visitErrorNode(ErrorNode node) { } /** * {@inheritDoc} * * <p> * The default implementation does nothing. * </p> */ @Override public void visitTerminal(TerminalNode node) { // Token t = node.getSymbol(); // doPrint(parser.getTokenNames()[t.getType()] + "'" + t.getText() + "'"); } @Override public String toString() { return stringBuilder.toString(); } }