/* * [The "BSD licence"] * Copyright (c) 2005-2008 Terence Parr * All rights reserved. * * Conversion to C#: * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ namespace Antlr.Runtime.Tree { /** <summary> * A TreeAdaptor that works with any Tree implementation. It provides * really just factory methods; all the work is done by BaseTreeAdaptor. * If you would like to have different tokens created than ClassicToken * objects, you need to override this and then set the parser tree adaptor to * use your subclass. * </summary> * * <remarks> * To get your parser to build nodes of a different type, override * create(Token), errorNode(), and to be safe, YourTreeClass.dupNode(). * dupNode is called to duplicate nodes during rewrite operations. * </remarks> */ public class CommonTreeAdaptor : BaseTreeAdaptor { /** <summary> * Duplicate a node. This is part of the factory; * override if you want another kind of node to be built. * </summary> * * <remarks> * I could use reflection to prevent having to override this * but reflection is slow. * </remarks> */ public override object DupNode(object t) { if (t == null) return null; return ((ITree)t).DupNode(); } public override object Create(IToken payload) { return new CommonTree(payload); } /** <summary> * Tell me how to create a token for use with imaginary token nodes. * For example, there is probably no input symbol associated with imaginary * token DECL, but you need to create it as a payload or whatever for * the DECL node as in ^(DECL type ID). * </summary> * * <remarks> * If you care what the token payload objects' type is, you should * override this method and any other createToken variant. * </remarks> */ public override IToken CreateToken(int tokenType, string text) { return new CommonToken(tokenType, text); } /** <summary> * Tell me how to create a token for use with imaginary token nodes. * For example, there is probably no input symbol associated with imaginary * token DECL, but you need to create it as a payload or whatever for * the DECL node as in ^(DECL type ID). * </summary> * * <remarks> * This is a variant of createToken where the new token is derived from * an actual real input token. Typically this is for converting '{' * tokens to BLOCK etc... You'll see * * r : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ; * * If you care what the token payload objects' type is, you should * override this method and any other createToken variant. * </remarks> */ public override IToken CreateToken(IToken fromToken) { return new CommonToken(fromToken); } /** <summary> * Track start/stop token for subtree root created for a rule. * Only works with Tree nodes. For rules that match nothing, * seems like this will yield start=i and stop=i-1 in a nil node. * Might be useful info so I'll not force to be i..i. * </summary> */ public override void SetTokenBoundaries(object t, IToken startToken, IToken stopToken) { if (t == null) return; int start = 0; int stop = 0; if (startToken != null) start = startToken.TokenIndex; if (stopToken != null) stop = stopToken.TokenIndex; ((ITree)t).TokenStartIndex = start; ((ITree)t).TokenStopIndex = stop; } public override int GetTokenStartIndex(object t) { if (t == null) return -1; return ((ITree)t).TokenStartIndex; } public override int GetTokenStopIndex(object t) { if (t == null) return -1; return ((ITree)t).TokenStopIndex; } public override string GetText(object t) { if (t == null) return null; return ((ITree)t).Text; } public override int GetType(object t) { if (t == null) return TokenTypes.Invalid; return ((ITree)t).Type; } /** <summary> * What is the Token associated with this node? If * you are not using CommonTree, then you must * override this in your own adaptor. * </summary> */ public override IToken GetToken(object t) { if (t is CommonTree) { return ((CommonTree)t).Token; } return null; // no idea what to do } public override object GetChild(object t, int i) { if (t == null) return null; return ((ITree)t).GetChild(i); } public override int GetChildCount(object t) { if (t == null) return 0; return ((ITree)t).ChildCount; } public override object GetParent(object t) { if (t == null) return null; return ((ITree)t).Parent; } public override void SetParent(object t, object parent) { if (t != null) ((ITree)t).Parent = (ITree)parent; } public override int GetChildIndex(object t) { if (t == null) return 0; return ((ITree)t).ChildIndex; } public override void SetChildIndex(object t, int index) { if (t != null) ((ITree)t).ChildIndex = index; } public override void ReplaceChildren(object parent, int startChildIndex, int stopChildIndex, object t) { if (parent != null) { ((ITree)parent).ReplaceChildren(startChildIndex, stopChildIndex, t); } } } }