/**
 * @(#)Grammar.java	17.03.2004
 * 
 * @author kst
 */
package commons.chartparser;
import java.lang.reflect.Array;
/**
 * Die Klasse stellt eine Regel dar.
 */
public class Rule
{

String   lexpr    = "";
String[] rexpr    = null;
Word     terminal = null;

// Konstruktor fuer grammatische Regel
@SuppressWarnings("unchecked")
public Rule(Grammar gramma, String line)
{
   int MINTOKENS = 2;
   String[] token = line.split(" ");
   if (token.length >= MINTOKENS)
   {
      lexpr = token[0];
      rexpr = (String[]) Array.newInstance(String.class, token.length - 2);
      StringBuilder rs = new StringBuilder();
      int shift = 1;
      for (int i = 1; i < token.length; i++)
      {
         if (!(token[i].equals("->") || token[i].equals("=>") || token[i].equals("=:") || token[i].equals("=")))
         {
            rexpr[i - shift] = token[i];
            rs.append(token[i]);
            rs.append(".*"); // fuer das pattern matching
            rs.append(" ");
         }
         else
         {
            shift++;
         }
      }
      gramma.linkeSeiten.add(lexpr, this);
      gramma.rechteSeiten.add(rs.toString().trim(), this);
      gramma.allRules.add(this);
   }
   else
   {
      Main.debug("Invalider Rules-Eintrag. Nur " + token.length + " Token in {" + line + "}");
   }
}

// Konstruktor fuer eine Terminal-Regel (Lexikon-Eintrag)
public Rule(String cat, String kgr, String form, Word word)
{
   lexpr = cat + (kgr == null ? "" : ":" + kgr);
   rexpr = (String[]) Array.newInstance(String.class, 1);
   rexpr[0] = form;
   this.terminal = word;
}

/**
 * Meldet, on die Regel ein Terminal ist.
 */
public boolean isTerminal ()
{
   return terminal != null;
}

/**
 * gibt das Terminal zurueck.
 */
public Word getTerminal ()
{
   return terminal;
}

/**
 * Gibt an, wieviele Elemente auf der rechten Seiten der Regel stehen. Bei "S -> NP VP" sind das 2.
 */
public int elements ()
{
   return rexpr.length;
}

/**
 * Gibt die linke Seite der Regel zurueck: Bei "S -> NP VP" ist das "S".
 */
public String lexpr ()
{
   return this.lexpr;
}

/**
 * Gibt die rechte Seite der Regel zurueck als Array zurueck: Bei "S -> NP VP" ist das "[NP][VP]"
 */
public String[] rexpr ()
{
   return this.rexpr;
}

/**
 * Gibt ein Element der rechten Seite der Regel zurueck zurueck: Bei "S -> NP VP"(0) ist das "[NP]"
 */
public String rexpr (int i)
{
   return rexpr[i];
}

/**
 * String-Repraesentation der Regel.
 */
public String toString ()
{
   StringBuilder sb = new StringBuilder();
   sb.append(lexpr);
   sb.append(" -> ");
   for (int i = 0; i < rexpr.length; i++)
   {
      sb.append(rexpr[i]);
      if (i < rexpr.length)
      {
         sb.append(" ");
      }
   }
   return sb.toString();
}
}