Package net.sourceforge.chaperon.build

Source Code of net.sourceforge.chaperon.build.State

/*
*  Copyright (C) Chaperon. All rights reserved.
*  -------------------------------------------------------------------------
*  This software is published under the terms of the Apache Software License
*  version 1.1, a copy of which has been included  with this distribution in
*  the LICENSE file.
*/

package net.sourceforge.chaperon.build;

import net.sourceforge.chaperon.model.grammar.Grammar;
import net.sourceforge.chaperon.model.grammar.Production;
import net.sourceforge.chaperon.model.symbol.Nonterminal;
import net.sourceforge.chaperon.model.symbol.Symbol;
import net.sourceforge.chaperon.model.symbol.SymbolList;
import net.sourceforge.chaperon.model.symbol.SymbolSet;
import net.sourceforge.chaperon.model.symbol.Terminal;

/**
* This class represents a set of items, which means positions of production, in production. These
* states were used to decribes states.
*
* @author <a href="mailto:stephan@apache.org">Stephan Michels</a>
* @version CVS $Id: State.java,v 1.8 2003/12/09 19:55:53 benedikta Exp $
*/
public class State
{
  private Production[] productions = new Production[0];
  private int[] positions = new int[0];

  // The symbols, which translate the states into other states
  private ShiftAction[] shiftactions = new ShiftAction[0];
  private ReduceAction[] reduceactions = new ReduceAction[0];
  private Grammar grammar;
  private static final EmptyList EMPTYLIST = new EmptyList();

  /**
   * Create an empty set of items.
   *
   * @param grammar Grammar.
   */
  public State(Grammar grammar)
  {
    this.grammar = grammar;
  }

  /**
   * Add a item to this set.
   *
   * @param production Production.
   * @param position Position in this production.
   *
   * @return True, if this item was added
   */
  public boolean addItem(Production production, int position)
  {
    for (int i = 0; i<productions.length; i++)
      if ((productions[i]==production) && (positions[i]==position))
        return false;

    Production[] newProductions = new Production[productions.length+1];
    int[] newPositions = new int[positions.length+1];

    System.arraycopy(productions, 0, newProductions, 0, productions.length);
    System.arraycopy(positions, 0, newPositions, 0, positions.length);

    newProductions[productions.length] = production;
    newPositions[positions.length] = position;

    productions = newProductions;
    positions = newPositions;

    // buildind closure for every item in state I
    SymbolList productiondefinition = production.getDefinition();

    // and not A=uv^w and w ist not empty
    if (position<productiondefinition.getSymbolCount())
    {
      Symbol symbol = productiondefinition.getSymbol(position)// A=u ^symbol w

      // for every item [A=u^Bv,a] in J and production B=w in G
      if (symbol instanceof Nonterminal)
      {
        // list of all productions B
        Production[] nestedproductions = grammar.getProductions(symbol);

        // for alle productions B
        for (int i = 0; i<nestedproductions.length; i++)

          // if J doesn't contain [B=^w] , should it added
          addItem(nestedproductions[i], 0);
      }
    }
    else
      addReduceAction(production);

    return true;
  }

  /**
   * Test, if all items from a other state exists in this state
   *
   * @param state Other state.
   *
   * @return True, if the state contains all items.
   */
  public boolean contains(State state)
  {
    int i;
    int j;
    int position;
    Production production;
    boolean found;

    for (i = 0; i<state.productions.length; i++)
    {
      production = state.productions[i];
      position = state.positions[i];

      found = false;
      for (j = 0; (j<productions.length) && !found; j++)
        found = ((productions[j]==production) && (positions[j]==position));

      if (!found)
        return false;
    }

    return true;
  }

  /**
   * Returns the count of items in this set.
   *
   * @return Count of items of the core.
   */
  public int getItemCount()
  {
    return productions.length;
  }

  /**
   * Returns true, if this set is empty.
   *
   * @return True, if this set is empty.
   */
  public boolean isEmpty()
  {
    return (productions.length==0);
  }

  /**
   * Compares two states.
   *
   * @param o Other state.
   *
   * @return True, if the states are equal.
   */
  public boolean equals(Object o)
  {
    if (o instanceof State)
    {
      State state = (State)o;

      if (state.getItemCount()!=getItemCount())
        return false;

      // The state must contain all item from this set.
      if (!contains(state))
        return false;

      // And this set must contain all item from the state
      if (!state.contains(this))
        return false;

      return true;
    }

    return false;
  }

  /**
   * Return the next Symbol, which follow the item.
   *
   * @param index Index the item.
   *
   * @return Symbol of the next position, otherwise the symbol for an empty list.
   */
  private Symbol getNextSymbol(int index)
  {
    SymbolList productiondefinition;

    if (positions[index]<((productiondefinition = productions[index].getDefinition()).getSymbolCount()))
      return productiondefinition.getSymbol(positions[index]);

    return EMPTYLIST;
  }

  public SymbolSet getNextTerminals()
  {
    SymbolSet set = new SymbolSet();

    SymbolList productiondefinition;
    for (int item = 0; item<productions.length; item++)
      if ((positions[item]<((productiondefinition = productions[item].getDefinition()).getSymbolCount())) &&
          (productiondefinition.getSymbol(positions[item]) instanceof Terminal))
        set.addSymbol(productiondefinition.getSymbol(positions[item]));

    return set;
  }

  public SymbolSet getNextNonterminals()
  {
    SymbolSet set = new SymbolSet();

    SymbolList productiondefinition;
    for (int item = 0; item<productions.length; item++)
      if ((positions[item]<((productiondefinition = productions[item].getDefinition()).getSymbolCount())) &&
          (productiondefinition.getSymbol(positions[item]) instanceof Nonterminal))
        set.addSymbol(productiondefinition.getSymbol(positions[item]));

    return set;
  }

  /**
   * Calculates the next state by a transition through the symbol X.
   *
   * @param symbol A Symbol, which can be a terminal or a nonterminal symbol.
   *
   * @return The next state, represented by an state.
   */
  public State jump(Symbol symbol)
  {
    State J = new State(grammar);

    // For every item [A=u^Xv,a] in I
    for (int i = 0; i<productions.length; i++)
    {
      if (getNextSymbol(i).equals(symbol))

        // add [A=uX^v,a] to J
        J.addItem(productions[i], positions[i]+1);
    }

    // jump(I,X) = closure(J)
    return J;
  }

  /**
   * Add a transition to this state.
   *
   * @param symbol Symbol, which forces a transition into another state.
   * @param state Destination state.
   */
  public boolean addShiftAction(Symbol symbol, State state)
  {
    for (int i = 0; i<shiftactions.length; i++)
      if (shiftactions[i].symbol.equals(symbol))
        return false;

    ShiftAction[] newshiftactions = new ShiftAction[shiftactions.length+1];
    System.arraycopy(shiftactions, 0, newshiftactions, 0, shiftactions.length);
    newshiftactions[shiftactions.length] = new ShiftAction(symbol, state);
    shiftactions = newshiftactions;
    return true;
  }

  /**
   * Returns the destination state of a transition.
   *
   * @param symbol Symbol, which force the transition.
   *
   * @return Destination state.
   */
  public ShiftAction getShiftAction(Symbol symbol)
  {
    for (int i = 0; i<shiftactions.length; i++)
      if (shiftactions[i].symbol.equals(symbol))
        return shiftactions[i];

    return null;
  }

  public ShiftAction[] getShiftActions()
  {
    return shiftactions;
  }

  public void addReduceAction(Production production)
  {
    for (int i = 0; i<reduceactions.length; i++)
      if (reduceactions[i].production==production)
        return;

    ReduceAction[] newreduceactions = new ReduceAction[reduceactions.length+1];
    for (int i = 0; i<reduceactions.length; i++)
      newreduceactions[i] = reduceactions[i];

    newreduceactions[reduceactions.length] = new ReduceAction(production);
    reduceactions = newreduceactions;
  }

  public ReduceAction[] getReduceActions()
  {
    int count = 0;
    for (int i = 0; i<productions.length; i++)
      if (getNextSymbol(i).equals(EMPTYLIST))  // for all A=u^ and all symbols in FOLLOW(A)

        count++;

    ReduceAction[] reduceactions = new ReduceAction[count];

    for (int i = 0; i<productions.length; i++)
      if (getNextSymbol(i).equals(EMPTYLIST))  // for all A=u^ and all symbols in FOLLOW(A)

        reduceactions[--count] = new ReduceAction(productions[i]);

    return reduceactions;
  }

  /**
   * Return a string representation of this state.
   *
   * @return String representation of this state.
   */
  public String toString()
  {
    StringBuffer buffer = new StringBuffer();

    SymbolList list;

    for (int productionindex = 0; productionindex<grammar.getProductionCount();
         productionindex++)
    {
      list = grammar.getProduction(productionindex).getDefinition();

      for (int position = 0; position<=list.getSymbolCount(); position++)
      {
        for (int item = 0; item<productions.length; item++)
          if ((productions[item]==grammar.getProduction(productionindex)) &&
              (positions[item]==position))
          {
            buffer.append(productions[item].getSymbol());
            buffer.append(" := ");

            for (int i = 0; i<list.getSymbolCount(); i++)
            {
              if (i==position)
                buffer.append(".");

              buffer.append(list.getSymbol(i)+" ");
            }

            if (position==list.getSymbolCount())
              buffer.append(".");

            buffer.append("\n");
            break;
          }
      }
    }

    return buffer.toString();
  }
}
TOP

Related Classes of net.sourceforge.chaperon.build.State

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.