content: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
   * This file is part of Beaver Parser Generator.                       *
   * Copyright (C) 2003,2004 Alexander Demenchuk <alder@softanvil.com>.  *
   * All rights reserved.                                                *
   * See the file "LICENSE" for the terms and conditions for copying,    *
   * distribution and modification of Beaver.                            *
   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  
  package beaver;
  
  /**
   * Represents a symbol of a grammar.
   */
  public class Symbol
  {
  	static private final int COLUMN_FIELD_BITS = 12;
  	static private final int COLUMN_FIELD_MASK = (1 << COLUMN_FIELD_BITS) - 1; 
  	
  	/**
  	 * Packes symbol "coordinates" into a single number.
  	 */
  	static public int makePosition(int line, int column)
  	{
  		return line << COLUMN_FIELD_BITS | column;
  	}
  	
  	/**
  	 * Extracts line number from a packed position.
  	 */
  	static public int getLine(int position)
  	{
  		return position >>> COLUMN_FIELD_BITS;
  	}
  	
  	/**
  	 * Extracts column number from a packed position.
  	 */
  	static public int getColumn(int position)
  	{
  		return position & COLUMN_FIELD_MASK;
  	}
  	
  	/**
  	 * Value assigned to this symbol. 
  	 */
  	public final Object value;
  
  	/** 
  	 * Numeric symbol ID. 
  	 */
  	protected short id;
  	
  	/**
  	 * Line and column where this symbol begins.
  	 */
  	protected int start;
  	
  	/**
  	 * Line and column where this symbol ends.
  	 */
  	protected int end;
  	
  	public Symbol(short id)
  	{
  		this.id = id;
  		this.value = null;
  	}
  
  	public Symbol(short id, Object value)
  	{
  		this.id    = id;
  		this.value = value;
  	}
  
  	public Symbol(short id, int start, int end)
  	{
  		this.id    = id;
  		this.value = null;
  		this.start = start;
  		this.end   = end;
  	}
  
  	public Symbol(short id, int left, int right, Object value)
  	{
  		this.id    = id;
  		this.value = value;
  		this.start = left;
  		this.end   = right;
  	}
  
  	public Symbol(short id, int start_line, int start_column, int length)
  	{
  		this.id    = id;
  		this.value = null;
  		this.start = makePosition(start_line, start_column);
  		this.end   = makePosition(start_line, start_column + length - 1);
  	}
  
  	public Symbol(short id, int start_line, int start_column, int length, Object value)
  	{
  		this.id    = id;
  		this.value = value;
  		this.start = makePosition(start_line, start_column);
  		this.end   = makePosition(start_line, start_column + length - 1);
  	}
  	
  	/**
  	 * Creates Symbol for non-symbolic results of action routines
  	 * 
  	 * @param value attached Symbol's value
  	 */
  	public Symbol(Object value)
  	{
  		this.value = value;
  	}
  
  	/**
  	 * Special case constructor that allows creation of explicitly Symbol-ized nonterminals.
  	 * <p/>
  	 * Used by classes descending from Symbol and which instances are returned by reduce actions.
  	 * In this case ID and symbol position will be assigned by the parser when reduce action
  	 * code returns this symbol.
  	 */
  	protected Symbol()
  	{
  		this.value = this;
  	}
  	
  	/**
  	 * Returns an ID of this symbol.
  	 * <p/>
  	 * This ID typically is, depending on a symbol type, either a terminal ID if a Symbol is a token
  	 * created and returned by a Scanner, or a nonterminal ID if a symbol was created by parser based
  	 * on that nonterminal definition. In the former case the ID is one of IDs generated by Beaver
  	 * for terminal symbols. The latter keeps IDs of nonterminal symbols.
  	 * 
  	 * @return symbol's ID
  	 */
  	public short getId()
  	{
  		return id;
  	}
  
  	/**
  	 * Returns a position in a source where this symbol starts.
  	 *
  	 * @return packed line and column numbers
  	 */
  	public int getStart()
  	{
  		return start;
  	}
  
  	/**
  	 * Returns a position in a source where this symbol ends.
  	 * 
  	 * @return packed line and column numbers
  	 */
  	public int getEnd()
  	{
  		return end;
  	}
  }
  