Package net.sourceforge.chaperon.build

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

/*
*  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.common.IntegerList;
import net.sourceforge.chaperon.model.grammar.Grammar;
import net.sourceforge.chaperon.model.symbol.SymbolSet;

import org.apache.commons.logging.Log;

import java.util.ArrayList;

/**
* This class contains a collection of item sets.
*
* @author <a href="mailto:stephan@apache.org">Stephan Michels</a>
* @version CVS $Id: ItemSetCollection.java,v 1.15 2003/12/09 19:55:52 benedikta Exp $
*/
public class ItemSetCollection
{
  private static final EndOfFile EOF = new EndOfFile();
  private static final int NOTCHANGED = 0;
  private static final int CHANGED = 1;
  private ArrayList itemsets = new ArrayList();
  private Grammar grammar;
  private FirstSetCollection firstsets;
  private SymbolSet tsymbols;
  private SymbolSet ntsymbols;
  private Log log;

  /**
   * Create a new collection of item sets, calculated with  the aid of the grammar. The constructor
   * calculates all state  and transitions and combine all itemsets with the same core.
   *
   * @param grammar Grammar.
   * @param firstsets First sets.
   */
  public ItemSetCollection(Grammar grammar, FirstSetCollection firstsets)
  {
    this(grammar, firstsets, null);
  }

  /**
   * Create a new collection of item sets, calculated with  the aid of the grammar. The constructor
   * calculates all state  and transitions and combine all itemsets with the same core.
   *
   * @param grammar Grammar
   * @param firstsets First sets.
   * @param log Log, which should be used.
   */
  public ItemSetCollection(Grammar grammar, FirstSetCollection firstsets, Log log)
  {
    this.grammar = grammar;
    this.firstsets = firstsets;
    this.log = log;

    SymbolSet symbols = grammar.getSymbols();

    tsymbols = symbols.getTerminals();
    ntsymbols = symbols.getNonterminals();

    // C = closure( [S'=^S,EOF] )
    IntegerList changedState = new IntegerList()// 0=not changed 1=changed

    addItemSet(getStartItemSet());
    changedState.add(CHANGED);

    boolean mustrepeat = false;
    for (int i = 0; i<getItemSetCount(); i++)
    {
      changedState.set(i, NOTCHANGED);

      ItemSet I = getItemSet(i);

      // J = goto(I,X) add to C, for all nonterminal and terminal symbols X
      // for the non terminal symbols
      SymbolSet nextnonterminals = I.getNextNonterminals();
      for (int j = 0; j<nextnonterminals.getSymbolCount(); j++)
      {
        ItemSet J = I.jump(nextnonterminals.getSymbol(j));

        if (!J.isEmpty())
        {
          int index = indexOfCore(J);
          if (index<0// if C doesn't contain J
          {
            index = addItemSet(J);

            changedState.add(CHANGED);
          }
          else  // otherwise the found state extends through J
          {
            if (getItemSet(index).addItemSet(J))  // if the found state change
            {
              if (index<changedState.getCount())
                changedState.set(index, CHANGED);
              else
                changedState.add(CHANGED);

              if (index<=i// if J before I, and J


                // was changed then must the loop repeat
                mustrepeat = true;
            }
          }

          I.setTransition(nextnonterminals.getSymbol(j), index)// stores the transition for this symbol
        }
      }

      // and for the terminal symbols
      SymbolSet nextterminals = I.getNextTerminals();
      for (int j = 0; j<nextterminals.getSymbolCount(); j++)
      {
        ItemSet J = I.jump(nextterminals.getSymbol(j));

        if (!J.isEmpty())
        {
          int index = indexOfCore(J);
          if (index<0// if C doesn't contain J
          {
            index = addItemSet(J);

            changedState.add(CHANGED);
          }
          else  // otherwise the found state extends through J
          {
            if (getItemSet(index).addItemSet(J))  // if the found state change
            {
              if (index<changedState.getCount())
                changedState.set(index, CHANGED);
              else
                changedState.add(CHANGED);

              if (index<=i// if J before I, and J


                // was changed then must the loop repeat
                mustrepeat = true;
            }
          }

          I.setTransition(nextterminals.getSymbol(j), index)// stores the transition for this symbol
        }
      }
    }

    do
    {
      mustrepeat = false;

      for (int i = 0; i<getItemSetCount(); i++)
        if (changedState.get(i)==CHANGED)
        {
          changedState.set(i, NOTCHANGED);

          ItemSet I = getItemSet(i);

          symbols = I.getShiftSymbols();

          for (int j = 0; j<symbols.getSymbolCount(); j++)
          {
            ItemSet J = I.jump(symbols.getSymbol(j));
            int index = I.getTransition(symbols.getSymbol(j));

            if (getItemSet(index).addItemSet(J))  // if the found state change
            {
              if (index<changedState.getCount())
                changedState.set(index, CHANGED);
              else
                changedState.add(CHANGED);

              if (index<=i// if J before I, and J


                // was changed then must the loop repeat
                mustrepeat = true;
            }
          }
        }
    }
    while (mustrepeat)// Repeat till no state changed
  }

  /**
   * Return the item set as start point for the calculation.
   *
   * @return Start point for the calculation.
   */
  private ItemSet getStartItemSet()
  {
    ItemSet I = new ItemSet(grammar, firstsets);
    IntegerList startlist = grammar.getProductionList(grammar.getStartSymbol());

    for (int i = 0; i<startlist.getCount(); i++)
      I.addItem(startlist.get(i), 0, EOF);

    return I.closure();
  }

  /**
   * Add a itemset to this collection.
   *
   * @param itemset Itemset.
   *
   * @return Index of the itemset in the collection.
   */
  public int addItemSet(ItemSet itemset)
  {
    int index = indexOf(itemset);

    if (index==-1)
    {
      itemsets.add(itemset);
      index = itemsets.size()-1;
    }

    return index;
  }

  /**
   * Return an item set given by an index.
   *
   * @param index Index of the itemset.
   *
   * @return Itemset.
   */
  public ItemSet getItemSet(int index)
  {
    return (ItemSet)itemsets.get(index);
  }

  /**
   * Return the count of item sets in this collection
   *
   * @return Count of itemsets.
   */
  public int getItemSetCount()
  {
    return itemsets.size();
  }

  /**
   * Return the index of an item set. If the collection does not contain the itemset, then return
   * this method will return -1.
   *
   * @param itemset Itemset, which should be found.
   *
   * @return Index of the itemset.
   */
  public int indexOf(ItemSet itemset)
  {
    for (int i = 0; i<itemsets.size(); i++)
      if (((ItemSet)itemsets.get(i)).equals(itemset))
        return i;

    return -1;
  }

  /**
   * If this collection contains the item set.
   *
   * @param itemset Itemset, which should be found.
   *
   * @return True, if the collection contains the itemset.
   */
  public boolean contains(ItemSet itemset)
  {
    for (int i = 0; i<itemsets.size(); i++)
      if (((ItemSet)itemsets.get(i)).equals(itemset))
        return true;

    return false;
  }

  /**
   * Return the index of an item set. If the collection does not contain the itemset, then this
   * method will  return -1. This Method compare only the core from the  item sets.
   *
   * @param itemset Itemset, which should be found.
   *
   * @return Index of the Itemset
   */
  public int indexOfCore(ItemSet itemset)
  {
    for (int i = 0; i<itemsets.size(); i++)
      if (((ItemSet)itemsets.get(i)).equalsCore(itemset))
        return i;

    return -1;
  }

  /**
   * If this collection contains the item set. This method compares only the core of the itemset.
   *
   * @param itemset Itemset, which should be found.
   *
   * @return True, if the collection contain the itemset.
   */
  public boolean containsCore(ItemSet itemset)
  {
    for (int i = 0; i<itemsets.size(); i++)
      if (((ItemSet)itemsets.get(i)).equalsCore(itemset))
        return true;

    return false;
  }

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

    for (int i = 0; i<getItemSetCount(); i++)
    {
      buffer.append("State ");
      buffer.append(String.valueOf(i));
      buffer.append(":\n");
      buffer.append(getItemSet(i).toString());
      buffer.append("\n");
    }

    return buffer.toString();
  }
}
TOP

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

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.