Q:

Create ParseTree (not AST)

I would like to create a parse tree (not an AST) with ANTLR in target language C#. This seems less then trivial, maybe I'm looking in all the wrong places.
So far, I tried to implement the partials in the generated parser as follows:
public partial class TestParser
{

   ParseTree pt = new ParseTree("root", null);

   partial void EnterRule(string ruleName, int ruleIndex)
   {
     ParseTree child = new ParseTree(ruleName, pt);
     pt.Children.Add(child);
     this.pt = child;
   }

   partial void LeaveRule(string ruleName, int ruleIndex)
   {
     this.pt = pt.Parent;
   }

}

with ParseTree being
public class ParseTree
{
    private List<ParseTree> children = new List<ParseTree>();

    public ParseTree(string name, ParseTree parent)
    {
        this.Parent = parent;
        this.Rule = name;
    }

    public ParseTree Parent { get; private set; }
    public string Rule { get; private set; }
    public List<ParseTree> Children { get { return children; } }

    public Boolean IsTerminal
    {
        get
        {
            return (children.Count == 0);
        }
    }

}

This works, but doesn't fulfill my goal: I can't get the matched tokens/text from this tree. Apart from that, it has an additional drawback: If I want to do this for multiple grammars, I have to copy-paste the partial class everywhere, since it's a partial of the TestParser, nothing higher up the foodchain.
I have looked at http://www.antlr.org/wiki/pages/viewpage.action?pageId=1760 but the generated Parser doesn't have a constructor that takes a ParseTreeBuilder.
Where to now?

A:

I've found a more or less reasonable solution to my problem. It has a major drawback: It only handles the text of production rules that consist only of tokens. This is sufficient for me, but might not be for you. A proper implementation should have token nodes too, so it can be properly walked.
Adaptor:
    public class ParseAdaptor : CommonTreeAdaptor
    {
        private C<ParseTree> container;

        public ParseAdaptor(C<ParseTree> container)
            : base()
        {
            this.container = container;
        }

        public override void AddChild(object t, object child)
        {
            base.AddChild(t, child);
            this.container.Value.Text += base.GetTree(child).Text;
        }

    }

The ParseTree implementation:
public class ParseTree
{
    private string ownText;
    private List<ParseTree> children = new List<ParseTree>();

    public ParseTree(string name, ParseTree parent)
    {
        this.Parent = parent;
        this.Rule = name;
    }

    public String Text
    {
        get
        {
            if (this.IsTerminal) return this.ownText;
            else
            {
                StringBuilder builder = new StringBuilder();
                foreach (ParseTree child in children)
                {
                    builder.Append(child.Text);
                }
                return builder.ToString();
            }
        }
        set
        {
            this.ownText = value;
        }
    }

    public ParseTree Parent { get; private set; }
    public string Rule { get; private set; }
    public List<ParseTree> Children { get { return children; } }

    public Boolean IsTerminal
    {
        get
        {
            return (children.Count == 0);
        }
    }

}
//Isn't this the silliest little thing you've ever seen?
//Where is a pointer when you need one?
public class C<T>
{
    public T Value { get; set; }
}

and it gets glued together with the partials:
    public partial class TestParser
    {

        C<ParseTree> parseTreeContainer = new C<ParseTree>() { Value = new ParseTree("root", null) };

        public ParseTree Tree
        {
            get
            {
                return parseTreeContainer.Value;
            }
            set
            {
                parseTreeContainer.Value = value;
            }
        }

        partial void CreateTreeAdaptor(ref ITreeAdaptor adaptor)
        {
            adaptor = new ParseAdaptor(this.parseTreeContainer);
        }

        partial void EnterRule(string ruleName, int ruleIndex)
        {
            ParseTree child = new ParseTree(ruleName, Tree);
            ParseTree parent = Tree;
            parent.Children.Add(child);
            Tree = child;
        }

        partial void LeaveRule(string ruleName, int ruleIndex)
        {
            Tree = Tree.Parent;
        }

    }

