blob: d0090858a91fd066235fe83799b8647350f8390c [file] [log] [blame]
/*
* [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 {
using IList = System.Collections.IList;
[System.Serializable]
public class RewriteRuleSubtreeStream : RewriteRuleElementStream {
public RewriteRuleSubtreeStream(ITreeAdaptor adaptor, string elementDescription)
: base(adaptor, elementDescription) {
}
/** <summary>Create a stream with one element</summary> */
public RewriteRuleSubtreeStream(ITreeAdaptor adaptor, string elementDescription, object oneElement)
: base(adaptor, elementDescription, oneElement) {
}
/** <summary>Create a stream, but feed off an existing list</summary> */
public RewriteRuleSubtreeStream(ITreeAdaptor adaptor, string elementDescription, IList elements)
: base(adaptor, elementDescription, elements) {
}
/** <summary>
* Treat next element as a single node even if it's a subtree.
* This is used instead of next() when the result has to be a
* tree root node. Also prevents us from duplicating recently-added
* children; e.g., ^(type ID)+ adds ID to type and then 2nd iteration
* must dup the type node, but ID has been added.
* </summary>
*
* <remarks>
* Referencing a rule result twice is ok; dup entire tree as
* we can't be adding trees as root; e.g., expr expr.
*
* Hideous code duplication here with super.next(). Can't think of
* a proper way to refactor. This needs to always call dup node
* and super.next() doesn't know which to call: dup node or dup tree.
* </remarks>
*/
public virtual object NextNode() {
//System.Console.WriteLine("nextNode: elements={0}, singleElement={1}", elements, ((ITree)singleElement).ToStringTree());
int n = Count;
if (dirty || (cursor >= n && n == 1)) {
// if out of elements and size is 1, dup (at most a single node
// since this is for making root nodes).
object el = NextCore();
return adaptor.DupNode(el);
}
// test size above then fetch
object tree = NextCore();
while (adaptor.IsNil(tree) && adaptor.GetChildCount(tree) == 1)
tree = adaptor.GetChild(tree, 0);
//System.Console.WriteLine("_next={0}", ((ITree)tree).ToStringTree());
object el2 = adaptor.DupNode(tree); // dup just the root (want node here)
return el2;
}
protected override object Dup(object el) {
return adaptor.DupTree(el);
}
}
}