00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 package org.antlr.runtime.debug;
00029
00030 import org.antlr.runtime.RecognitionException;
00031 import org.antlr.runtime.Token;
00032 import org.antlr.runtime.BaseRecognizer;
00033 import org.antlr.runtime.tree.TreeAdaptor;
00034
00035 import java.io.*;
00036 import java.net.ServerSocket;
00037 import java.net.Socket;
00038
00045 public class DebugEventSocketProxy extends BlankDebugEventListener {
00046 public static final int DEFAULT_DEBUGGER_PORT = 0xC001;
00047 protected int port = DEFAULT_DEBUGGER_PORT;
00048 protected ServerSocket serverSocket;
00049 protected Socket socket;
00050 protected String grammarFileName;
00051 protected PrintWriter out;
00052 protected BufferedReader in;
00053
00055 protected BaseRecognizer recognizer;
00056
00061 protected TreeAdaptor adaptor;
00062
00063 public DebugEventSocketProxy(BaseRecognizer recognizer, TreeAdaptor adaptor) {
00064 this(recognizer, DEFAULT_DEBUGGER_PORT, adaptor);
00065 }
00066
00067 public DebugEventSocketProxy(BaseRecognizer recognizer, int port, TreeAdaptor adaptor) {
00068 this.grammarFileName = recognizer.getGrammarFileName();
00069 this.adaptor = adaptor;
00070 this.port = port;
00071 }
00072
00073 public void handshake() throws IOException {
00074 if ( serverSocket==null ) {
00075 serverSocket = new ServerSocket(port);
00076 socket = serverSocket.accept();
00077 socket.setTcpNoDelay(true);
00078 OutputStream os = socket.getOutputStream();
00079 OutputStreamWriter osw = new OutputStreamWriter(os, "UTF8");
00080 out = new PrintWriter(new BufferedWriter(osw));
00081 InputStream is = socket.getInputStream();
00082 InputStreamReader isr = new InputStreamReader(is, "UTF8");
00083 in = new BufferedReader(isr);
00084 out.println("ANTLR "+ DebugEventListener.PROTOCOL_VERSION);
00085 out.println("grammar \""+ grammarFileName);
00086 out.flush();
00087 ack();
00088 }
00089 }
00090
00091 public void commence() {
00092
00093 }
00094
00095 public void terminate() {
00096 transmit("terminate");
00097 out.close();
00098 try {
00099 socket.close();
00100 }
00101 catch (IOException ioe) {
00102 ioe.printStackTrace(System.err);
00103 }
00104 }
00105
00106 protected void ack() {
00107 try {
00108 in.readLine();
00109 }
00110 catch (IOException ioe) {
00111 ioe.printStackTrace(System.err);
00112 }
00113 }
00114
00115 protected void transmit(String event) {
00116 out.println(event);
00117 out.flush();
00118 ack();
00119 }
00120
00121 public void enterRule(String grammarFileName, String ruleName) {
00122 transmit("enterRule "+grammarFileName+" "+ruleName);
00123 }
00124
00125 public void enterAlt(int alt) {
00126 transmit("enterAlt "+alt);
00127 }
00128
00129 public void exitRule(String grammarFileName, String ruleName) {
00130 transmit("exitRule "+grammarFileName+" "+ruleName);
00131 }
00132
00133 public void enterSubRule(int decisionNumber) {
00134 transmit("enterSubRule "+decisionNumber);
00135 }
00136
00137 public void exitSubRule(int decisionNumber) {
00138 transmit("exitSubRule "+decisionNumber);
00139 }
00140
00141 public void enterDecision(int decisionNumber) {
00142 transmit("enterDecision "+decisionNumber);
00143 }
00144
00145 public void exitDecision(int decisionNumber) {
00146 transmit("exitDecision "+decisionNumber);
00147 }
00148
00149 public void consumeToken(Token t) {
00150 String buf = serializeToken(t);
00151 transmit("consumeToken "+buf);
00152 }
00153
00154 public void consumeHiddenToken(Token t) {
00155 String buf = serializeToken(t);
00156 transmit("consumeHiddenToken "+buf);
00157 }
00158
00159 public void LT(int i, Token t) {
00160 if(t != null)
00161 transmit("LT "+i+" "+serializeToken(t));
00162 }
00163
00164 public void mark(int i) {
00165 transmit("mark "+i);
00166 }
00167
00168 public void rewind(int i) {
00169 transmit("rewind "+i);
00170 }
00171
00172 public void rewind() {
00173 transmit("rewind");
00174 }
00175
00176 public void beginBacktrack(int level) {
00177 transmit("beginBacktrack "+level);
00178 }
00179
00180 public void endBacktrack(int level, boolean successful) {
00181 transmit("endBacktrack "+level+" "+(successful?TRUE:FALSE));
00182 }
00183
00184 public void location(int line, int pos) {
00185 transmit("location "+line+" "+pos);
00186 }
00187
00188 public void recognitionException(RecognitionException e) {
00189 StringBuffer buf = new StringBuffer(50);
00190 buf.append("exception ");
00191 buf.append(e.getClass().getName());
00192
00193 buf.append(" ");
00194 buf.append(e.index);
00195 buf.append(" ");
00196 buf.append(e.line);
00197 buf.append(" ");
00198 buf.append(e.charPositionInLine);
00199 transmit(buf.toString());
00200 }
00201
00202 public void beginResync() {
00203 transmit("beginResync");
00204 }
00205
00206 public void endResync() {
00207 transmit("endResync");
00208 }
00209
00210 public void semanticPredicate(boolean result, String predicate) {
00211 StringBuffer buf = new StringBuffer(50);
00212 buf.append("semanticPredicate ");
00213 buf.append(result);
00214 serializeText(buf, predicate);
00215 transmit(buf.toString());
00216 }
00217
00218
00219
00220 public void consumeNode(Object t) {
00221 StringBuffer buf = new StringBuffer(50);
00222 buf.append("consumeNode");
00223 serializeNode(buf, t);
00224 transmit(buf.toString());
00225 }
00226
00227 public void LT(int i, Object t) {
00228 int ID = adaptor.getUniqueID(t);
00229 String text = adaptor.getText(t);
00230 int type = adaptor.getType(t);
00231 StringBuffer buf = new StringBuffer(50);
00232 buf.append("LN ");
00233 buf.append(i);
00234 serializeNode(buf, t);
00235 transmit(buf.toString());
00236 }
00237
00238 protected void serializeNode(StringBuffer buf, Object t) {
00239 int ID = adaptor.getUniqueID(t);
00240 String text = adaptor.getText(t);
00241 int type = adaptor.getType(t);
00242 buf.append(" ");
00243 buf.append(ID);
00244 buf.append(" ");
00245 buf.append(type);
00246 Token token = adaptor.getToken(t);
00247 int line = -1;
00248 int pos = -1;
00249 if ( token!=null ) {
00250 line = token.getLine();
00251 pos = token.getCharPositionInLine();
00252 }
00253 buf.append(" ");
00254 buf.append(line);
00255 buf.append(" ");
00256 buf.append(pos);
00257 int tokenIndex = adaptor.getTokenStartIndex(t);
00258 buf.append(" ");
00259 buf.append(tokenIndex);
00260 serializeText(buf, text);
00261 }
00262
00263
00264
00265
00266 public void nilNode(Object t) {
00267 int ID = adaptor.getUniqueID(t);
00268 transmit("nilNode "+ID);
00269 }
00270
00271 public void errorNode(Object t) {
00272 int ID = adaptor.getUniqueID(t);
00273 String text = t.toString();
00274 StringBuffer buf = new StringBuffer(50);
00275 buf.append("errorNode ");
00276 buf.append(ID);
00277 buf.append(" ");
00278 buf.append(Token.INVALID_TOKEN_TYPE);
00279 serializeText(buf, text);
00280 transmit(buf.toString());
00281 }
00282
00283 public void createNode(Object t) {
00284 int ID = adaptor.getUniqueID(t);
00285 String text = adaptor.getText(t);
00286 int type = adaptor.getType(t);
00287 StringBuffer buf = new StringBuffer(50);
00288 buf.append("createNodeFromTokenElements ");
00289 buf.append(ID);
00290 buf.append(" ");
00291 buf.append(type);
00292 serializeText(buf, text);
00293 transmit(buf.toString());
00294 }
00295
00296 public void createNode(Object node, Token token) {
00297 int ID = adaptor.getUniqueID(node);
00298 int tokenIndex = token.getTokenIndex();
00299 transmit("createNode "+ID+" "+tokenIndex);
00300 }
00301
00302 public void becomeRoot(Object newRoot, Object oldRoot) {
00303 int newRootID = adaptor.getUniqueID(newRoot);
00304 int oldRootID = adaptor.getUniqueID(oldRoot);
00305 transmit("becomeRoot "+newRootID+" "+oldRootID);
00306 }
00307
00308 public void addChild(Object root, Object child) {
00309 int rootID = adaptor.getUniqueID(root);
00310 int childID = adaptor.getUniqueID(child);
00311 transmit("addChild "+rootID+" "+childID);
00312 }
00313
00314 public void setTokenBoundaries(Object t, int tokenStartIndex, int tokenStopIndex) {
00315 int ID = adaptor.getUniqueID(t);
00316 transmit("setTokenBoundaries "+ID+" "+tokenStartIndex+" "+tokenStopIndex);
00317 }
00318
00319
00320
00321
00322 public void setTreeAdaptor(TreeAdaptor adaptor) { this.adaptor = adaptor; }
00323 public TreeAdaptor getTreeAdaptor() { return adaptor; }
00324
00325 protected String serializeToken(Token t) {
00326 StringBuffer buf = new StringBuffer(50);
00327 buf.append(t.getTokenIndex()); buf.append(' ');
00328 buf.append(t.getType()); buf.append(' ');
00329 buf.append(t.getChannel()); buf.append(' ');
00330 buf.append(t.getLine()); buf.append(' ');
00331 buf.append(t.getCharPositionInLine());
00332 serializeText(buf, t.getText());
00333 return buf.toString();
00334 }
00335
00336 protected void serializeText(StringBuffer buf, String text) {
00337 buf.append(" \"");
00338 if ( text==null ) {
00339 text = "";
00340 }
00341
00342
00343 text = escapeNewlines(text);
00344 buf.append(text);
00345 }
00346
00347 protected String escapeNewlines(String txt) {
00348 txt = txt.replaceAll("%","%25");
00349 txt = txt.replaceAll("\n","%0A");
00350 txt = txt.replaceAll("\r","%0D");
00351 return txt;
00352 }
00353 }
00354