我用eclipse的antlr 4为我的语法(表达式)构建了ast, 我想建立访问者访问ast并打印ast ... 我如何建立访客?
Hello.g4:
/**
* Define a grammar called Hello
*/
grammar Hello;
@parser::header{
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import ast.*;
}
@parser::members{
Map<String,Object> symbolTable=new HashMap<String,Object>();
}
r : PROGRAM ID BRACKET_OPEN
{
List<ASTNode> body= new ArrayList<ASTNode>();
}
(sentence{body.add($sentence.node);})*
BRACKET_CLOSE
{
for(ASTNode n: body )
{
n.excute();
}
}
; // match keyword hello followed by an identifier
sentence returns [ASTNode node]:println{$node=$println.node;};
println returns [ASTNode node]:PRINTLN expression SEMICOLON {$node=new Println($expression.node);};
expression returns [ASTNode node]:
t1=factor {$node=$t1.node;}
(PLUS t2=factor{$node= new Addition($node,$t2.node);}
|MINUS t2=factor{$node= new Sub($node,$t2.node);}
)*
;
factor returns [ASTNode node]: t1=term {$node=$t1.node;}
(MULT t2=term{$node= new Multiplication($node,$t2.node);}
| DIV t2=term{$node= new Div($node,$t2.node);}
)*
;
term returns [ASTNode node]:
NUMBER {$node=new Constant(Integer.parseInt($NUMBER.text));}
| ID {}
| PAR_OPEN expression {$node=$expression.node;} PAR_CLOSE
;
PROGRAM:'program';
VAR:'var';
PRINTLN:'println';
INT :'int';
DOUBLE :'double';
STRING :'string';
MULT :'*';
PLUS :'+';
MINUS:'-';
DIV:'/' ;
ASSIGN:'=';
BRACKET_OPEN : '{';
BRACKET_CLOSE : '}';
PAR_OPEN :'(';
PAR_CLOSE :')';
SEMICOLON:';';
ID : [a-zA-Z_][a-zA-Z0-9_]* ; // match lower-case identifiers
NUMBER :[0-9]+;
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines
ASTNode接口:
package ast;
public interface ASTNode {
public Object excute();
}
例如附加类:
package ast;
public class Addition implements ASTNode {
private ASTNode operand1;
private ASTNode operand2;
public Addition(ASTNode operand1, ASTNode operand2) {
super();
this.operand1 = operand1;
this.operand2 = operand2;
}
@Override
public Object excute() {
// TODO Auto-generated method stub
return (int)operand1.excute() + (int)operand2.excute();
}
}
主要课程:
import java.io.IOException;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
import java.io.*;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class MyServlet
*/
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public MyServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try
{
String comment = request.getParameter("preview-form-comment") ;
request.setAttribute("data", comment);
ANTLRInputStream input = new ANTLRInputStream( comment);
HelloLexer lexer = new HelloLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
HelloParser parser = new HelloParser(tokens);
lexer.removeErrorListener(ConsoleErrorListener.INSTANCE);
parser.removeErrorListener(ConsoleErrorListener.INSTANCE);
ParseTree tree = parser.r(); // begin parsing at rule 'r' http://localhost:8080/MyParser/
// HelloVisitor visitor= new HelloVisitor();
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
RequestDispatcher rd=request.getRequestDispatcher("/index.jsp");
rd.include(request, response);
// writer.println("<h4>Your Comment Is :</h4>");
//ANTLRInputStream input=new ANTLRInputStream(System.in);
// writer.println("<br><font color=black>"+comment+"</font>");
writer.println("<br><font color=black>"+tree.toStringTree(parser)+"</font>");
writer.close();
}
catch(Exception exception)
{
exception.printStackTrace();
}
}
}