[antlr-interest] Remote Debugging with C#

Johannes Luber jaluber at gmx.de
Fri Jun 29 15:53:06 PDT 2007


Markus Kuhla wrote:
> Hi,
> 
> I don't know if there's any differences for C#, but in Java I do:
> 1. do not generate in ANTLRworks (it ignores -debug option)
> 2. the generated parser has a second constructer argument, an DebugEventListener. I use it for the parse tree:
> 
> ParseTreeBuilder builder = new ParseTreeBuilder("start");
> testParser parser = new testParser(tokens, builder);
> parser.start();
> ParseTree pt = ((ParseTreeBuilder)builder).getTree();

I've noticed that the argument of ParseTreeBuilder is supposed to be the
grammar name, not the start rule. A short look with .NET Reflector into
the assembly told me (yes, that tool makes source code access nearly
superfluous - only a shame, that no comments survive the compilation and
that I have thought of it only a few days ago :( ). And isn't the
conversion of the ParseTreeBuilder builder into a ParseTreeBuilder kinda
superfluous here?

> But as I know your other posts, your problem may be much harder ;)

I know. I have sometimes the feeling that I'm the pilot of a supersonic
aircraft and I still have to push my vehicle by hand. :D But back the topic:

You are truly prophetic - I couldn't simply compile the code. Turns out,
that the template for C# uses constantly "location" instead "Location".
Then "dbg.RecognitionException(nvae);" is used, where no "nvae" is
available. Instead I had to replace those occurrences with "nvae_d4s0"
and similar (there were really many of those...). Then I've got this line:

protected ITreeAdaptor adaptor = new DebugTreeAdaptor(dbg, new
CommonTreeAdaptor());

It is trying to initialize a member via the non-constructor way with a
constructor-only argument, which of course the compiler doesn't know
about. I removed the assignment and added in each constructor the line:

adaptor = new DebugTreeAdaptor(dbg, new CommonTreeAdaptor());

Actually, in the one-parameter constructor I used "null" instead "dbg".
It would cause NullReferenceExceptions everywhere, if the TreeAdaptor
isn't set afterwards, but that seems to be the consequence anyway, as
this constructor chains to the one-argument base constructor
(Interestingly, the one-argument constructor has the line

ruleMemo = new IDictionary[154+1];

but the two-argument constructor does not. I'm further astonished that
no constructor chaining is done from the one-argument constructor to the
two-argument constructor.)

Then the DFA class DFA71 wants to access the dbg field from the parser
class, but the compiler doesn't allow this without having a reference to
the parser class. I had to add another constructor parameter to DFA71
and change things into the following:

private void InitializeCyclicDFAs()
{
     this.dfa71 = new DFA71(this, this.dbg);
}

And in DFA71:

IDebugEventListener dbg;

public DFA71(BaseRecognizer recognizer, IDebugEventListener dbg)
{
    this.recognizer = recognizer;
    this.decisionNumber = 71;
    this.eot = DFA71_eot;
    this.eof = DFA71_eof;
    this.min = DFA71_min;
    this.max = DFA71_max;
    this.accept     = DFA71_accept;
    this.special    = DFA71_special;
    this.transition = DFA71_transition;
    this.dbg = dbg;
}

After that it was easy to add override to

public virtual override void Error(NoViableAltException nvae)

because otherwise "virtual" would be wasted.

Nonetheless, I'm still missing some pieces. What I am supposed to do
with with the ParseTree pt? And when do I have to start ANTLRworks in
the remote debugging mode?

Best regards,
Johannes Luber


More information about the antlr-interest mailing list