Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   [The "BSD license"]
   Copyright (c) 2005-2009 Terence Parr
   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.
 package org.antlr.runtime.tree;
 import java.util.List;

A generic list of elements tracked in an alternative to be used in a -> rewrite rule. We need to subclass to fill in the next() method, which returns either an AST node wrapped around a token payload or an existing subtree. Once you start next()ing, do not try to add more elements. It will break the cursor tracking I believe.

See also:
RewriteRuleTokenStream TODO: add mechanism to detect/puke on modification after reading from stream
 public abstract class RewriteRuleElementStream {
Cursor 0..n-1. If singleElement!=null, cursor is 0 until you next(), which bumps it to 1 meaning no more elements.
 	protected int cursor = 0;

Track single elements w/o creating a list. Upon 2nd add, alloc list
 	protected Object singleElement;

The list of tokens or subtrees we are tracking
 	protected List elements;

Once a node / subtree has been used in a stream, it must be dup'd from then on. Streams are reset after subrules so that the streams can be reused in future subrules. So, reset must set a dirty bit. If dirty, then next() always returns a dup. I wanted to use "naughty bit" here, but couldn't think of a way to use "naughty". TODO: unused?
 	protected boolean dirty = false;

The element or stream description; usually has name of the token or rule reference that this list tracks. Can include rulename too, but the exception would track that info.
 	protected TreeAdaptor adaptor;
 	public RewriteRuleElementStream(TreeAdaptor adaptorString elementDescription) {
 		this. = elementDescription;
 		this. = adaptor;

Create a stream with one element
 									String elementDescription,
 									Object oneElement)

Create a stream, but feed off an existing list
 									String elementDescription,
 									List elements)
 		this. = null;
 		this. = elements;

Reset the condition of this stream so that it appears we have not consumed any of its elements. Elements themselves are untouched. Once we reset the stream, any future use will need duplicates. Set the dirty bit.
	public void reset() {
		 = 0;
		 = true;
	public void add(Object el) {
		//System.out.println("add '"+elementDescription+"' is "+el);
		if ( el==null ) {
		if ( !=null ) { // if in list, just add
		if (  == null ) { // no elements yet, track w/o list
		// adding 2nd element, move to list
		 = new ArrayList(5);
		 = null;

Return the next element in the stream. If out of elements, throw an exception unless size()==1. If size is 1, then return elements[0]. Return a duplicate node/subtree if stream is out of elements and size==1. If we've already used the element, dup (dirty bit set).
	public Object nextTree() {
		int n = size();
		if (  || (>=n && n==1) ) {
			// if out of elements and size is 1, dup
			Object el = _next();
			return dup(el);
		// test size above then fetch
		Object el = _next();
		return el;

do the work of getting the next element, making sure that it's a tree node or subtree. Deal with the optimization of single- element list versus list of size > 1. Throw an exception if the stream is empty or we're out of elements and size>1. protected so you can override in a subclass if necessary.
	protected Object _next() {
		int n = size();
		if ( n ==0 ) {
		if ( >= n) { // out of elements?
			if ( n ==1 ) {  // if size is 1, it's ok; return and we'll dup
			// out of elements and size was not 1, so we can't dup
		// we have elements
		if ( !=null ) {
			++; // move cursor even for single element list
		// must have more than one in list, pull from elements
		return o;

When constructing trees, sometimes we need to dup a token or AST subtree. Dup'ing a token means just creating another AST node around it. For trees, you must call the adaptor.dupTree() unless the element is for a tree root; then it must be a node dup.
	protected abstract Object dup(Object el);

Ensure stream emits trees; tokens must be converted to AST nodes. AST nodes can be passed through unmolested.
	protected Object toTree(Object el) {
		return el;
	public boolean hasNext() {
		 return ( != null &&  < 1) ||
			   (!=null &&  < .size());
	public int size() {
		int n = 0;
		if (  != null ) {
			n = 1;
		if ( !=null ) {
			return .size();
		return n;
	public String getDescription() {
New to GrepCode? Check out our FAQ X