package org.deved.antlride.runtime;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import org.antlr.runtime.ANTLRFileStream;
import org.antlr.runtime.BaseRecognizer;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.TokenSource;
import org.antlr.runtime.TokenStream;
import org.antlr.runtime.debug.BlankDebugEventListener;
import org.antlr.runtime.debug.DebugEventListener;
import org.antlr.runtime.debug.DebugEventSocketProxy;
import org.antlr.runtime.debug.DebugParser;
import org.antlr.runtime.debug.DebugTokenStream;
import org.antlr.runtime.debug.RemoteDebugEventSocketListener;
import org.antlr.runtime.tree.CommonTreeAdaptor;
import org.antlr.runtime.tree.TreeAdaptor;
public class LaunchParser implements Runnable {
private class Debugger extends DebugEventSocketProxy {
private BaseRecognizer fRecognizer;
private int fDecision = 0;
private java.util.Collection msgs = new java.util.ArrayList();
public Debugger(BaseRecognizer recognizer, int port, TreeAdaptor adaptor) {
super(recognizer, port, adaptor);
this.fRecognizer = recognizer;
}
public void enterDecision(int decisionNumber) {
fDecision++;
super.enterDecision(decisionNumber);
}
public void exitDecision(int decisionNumber) {
fDecision--;
super.exitDecision(decisionNumber);
}
public void recognitionException(RecognitionException e) {
StringBuffer buf = new StringBuffer(50);
buf.append("exception\t");
String className = e.getClass().getName();
className = className.substring(className.lastIndexOf('.') + 1);
buf.append(className);
// dump only the data common to all exceptions for now
buf.append("\t");
buf.append(e.index);
buf.append("\t");
buf.append(e.line);
buf.append("\t");
buf.append(e.charPositionInLine);
buf.append("\t\"");
String msg = getErrMessage(e);
if (fDecision == 0 && !msgs.contains(msg)) {
System.err.println(msg);
msgs.add(msg);
}
buf.append(msg);
transmit(buf.toString());
}
protected String getErrMessage(RecognitionException e) {
String hdr = fRecognizer.getErrorHeader(e);
String msg = fRecognizer.getErrorMessage(e, fRecognizer
.getTokenNames());
String errmsg = hdr + " " + msg;
return escapeNewlines(errmsg);
}
public void setTreeAdaptorHook(TreeAdaptor adaptor) {
// ANTLR 3.0.x compatible
this.adaptor = adaptor;
}
}
private Map args = new HashMap();
public LaunchParser(String[] args) {
for (int i = 0; i < args.length; i = i + 2) {
String key = args[i];
String val = args[i + 1];
this.args.put(key, val);
}
}
public void launch() throws Exception {
// ++++++++++++++++++++++++++
// create lexer
// ++++++++++++++++++++++++++
String testCase = (String) args.get("-testCase");
ANTLRFileStream stream = new ANTLRFileStream(testCase);
String lexerClassName = (String) args.get("-lexer");
Class lexerClass = Class.forName(lexerClassName);
Constructor lexerConstructor = lexerClass
.getDeclaredConstructor(new Class[] { CharStream.class });
TokenSource lexer = (TokenSource) lexerConstructor
.newInstance(new Object[] { stream });
// ++++++++++++++++++++++++++
// create token stream
// ++++++++++++++++++++++++++
CommonTokenStream tokens = new CommonTokenStream(lexer);
// ++++++++++++++++++++++++++
// create parser
// ++++++++++++++++++++++++++
String parserClassName = (String) args.get("-parser");
Class parserClass = Class.forName(parserClassName);
Constructor parserConstructor = parserClass
.getDeclaredConstructor(new Class[] { TokenStream.class,
DebugEventListener.class });
Object parser = parserConstructor.newInstance(new Object[] { tokens,
null });
// start the debugger
startDebugger(tokens, parser);
// ++++++++++++++++++++++++++
// rule name
// ++++++++++++++++++++++++++
String ruleName = (String) args.get("-ruleName");
// invoke rule
invokeRule(ruleName, lexer, parser);
}
private Debugger startDebugger(TokenStream input, Object parser) {
int port = Integer.parseInt((String) args.get("-port"));
DebugParser debugParser = (DebugParser) parser;
Debugger debugger = new Debugger(debugParser, port, null);
TreeAdaptor adap = new CommonTreeAdaptor();
debugParser.setDebugListener(debugger);
debugParser.setTokenStream(new DebugTokenStream(input, debugger));
try {
debugger.handshake();
} catch (IOException ioe) {
debugParser.reportError(ioe);
}
// ++++++ parser deps
setTreeAdaptor(parser, adap);
Field[] fields = parser.getClass().getDeclaredFields();
if(fields != null) {
for (int i = 0; i < fields.length; i++) {
Class parserClass = fields[i].getType();
if(DebugParser.class.isAssignableFrom(parserClass)) {
try {
DebugParser delegate = (DebugParser) fields[i].get(parser);
delegate.setDebugListener(debugger);
setTreeAdaptor(delegate, adap);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
// ++++++ debugger deps
try {
// ANTLR 3.0.x compatible
java.lang.reflect.Method setTreeAdaptor = findMethod(debugger
.getClass(), "setTreeAdaptor",
new Class[] { TreeAdaptor.class });
setTreeAdaptor.invoke(debugger, new Object[] { adap });
} catch (Exception ex) {
debugger.setTreeAdaptorHook(adap);
}
return debugger;
}
private void setTreeAdaptor(Object parser, TreeAdaptor adap) {
try {
// ANTLR 3.0.x compatible
java.lang.reflect.Method setTreeAdaptor = findMethod(parser
.getClass(), "setTreeAdaptor",
new Class[] { TreeAdaptor.class });
setTreeAdaptor.invoke(parser, new Object[] { adap });
} catch (Exception ex) {
}
}
private void invokeRule(String ruleName, Object lexer, Object parser)
throws Exception {
Class clazz = null;
Object instance = null;
if (isLexerRule(ruleName)) {
instance = lexer;
clazz = lexer.getClass();
ruleName = "m" + ruleName;
} else {
instance = parser;
clazz = parser.getClass();
}
java.lang.reflect.Method rule = findMethod(clazz, ruleName,
new Class[0]);
rule.invoke(instance, null);
}
private boolean isLexerRule(String ruleName) {
return Character.isUpperCase(ruleName.charAt(0));
}
private java.lang.reflect.Method findMethod(Class clazz, String methodName,
Class[] params) {
try {
while (clazz != null) {
java.lang.reflect.Method m = clazz.getDeclaredMethod(
methodName, params);
if (m != null)
return m;
clazz = clazz.getSuperclass();
}
} catch (Exception ex) {
// shhhhh
}
throw new IllegalArgumentException("Invalid method name: \""
+ methodName + "\". Execution was cancelled");
}
public static void main(String[] args) throws Exception {
LaunchParser parser = new LaunchParser(args);
parser.launch();
}
public void run() {
try {
Thread.sleep(1000);
DebugEventListener del = new BlankDebugEventListener();
int port = Integer.parseInt((String) args.get("-port"));
RemoteDebugEventSocketListener rdesl = new RemoteDebugEventSocketListener(
del, "localhost", port);
rdesl.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}