Package fmg.fmg8.earleyErkenner

Source Code of fmg.fmg8.earleyErkenner.EarleyGrammatik

/*
* Datei:            Grammatik.java
* Autor(en):        Lukas K�nig
* Java-Version:     1.4
* Erstellt (vor): 08.06.2007
*
* (c) Lukas K�nig, die Datei unterliegt der LGPL
* -> http://www.gnu.de/lgpl-ger.html
*/

package fmg.fmg8.earleyErkenner;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;

import fmg.fmg8.sonstiges.SonstMeth;


/**
* Implementiert eine Datenstruktur f�r eine kontextfreie Grammatik in der
* Form, wie sie der Earley-Parser ben�tigt (mit "Punkt"). Der Punkt befindet
* sich immer am Anfang der Regeln. Die Grammatik sollte w�hrend
* des Parsens nicht ver�ndert werden.
* Durch Aufruf der Methode <code>init()</code> kann die Grammatik wieder auf
* den urspr�nglichen Zustand gesetzt werden.
*
* @author Lukas K�nig
*/
public class EarleyGrammatik implements Serializable {

    /**
     * Generiert am 26.07.2007.
     */
    private static final long serialVersionUID = -8810080615113388683L;

    /**
     * Grammatikregeln vom Typ <code>EarleyRegel</code> der Grammatik.
     */
    private ArrayList<EarleyRegel> regeln;

    /**
     * Die Terminalsymbole der Grammatik.
     */
    private ArrayList<String> terminale;

    /**
     * Die Nichtterminalsymbole der Grammatik.
     */
    private ArrayList<String> nichtTerminale;

    /**
     * Konstruktor, der eine Grammatik aus einer Datei einliest und alle Felder
     * initialisiert.
     *
     * @param dateiname  Der Name der Grammatikdatei.
     */
    public EarleyGrammatik(final String dateiname) {
        this.liesGrammatik(dateiname);
        this.extrahiereSymbole();
    }

    /**
     * Tr�gt die zu den Grammatikregeln geh�renden Terminal- und
     * Nichtterminalsymbole in die Felder <code>terminale</code>
     * und <code>nichtterminale</code> ein. Dabei muss bei allen Regeln der
     * Punkt ganz links stehen!
     * <P>
     * Nichtterminalsymbole sind alle Symbole, die mindestens einmal
     * auf der linken Seite einer Regel stehen. Terminalsymbole sind alle
     * �brigen Symbole. Als Startsymbol wird das Symbol definiert, das als
     * erstes in der Struktur steht, also
     * <code>this.nichtTerminale.get(0)</code>.
     * Dies entspricht auch dem ersten Symbol in der Grammatikdatei.
     */
    private void extrahiereSymbole() {
        Iterator<EarleyRegel> it;
        Iterator<String> it2;
        EarleyRegel aktR;
        String aktSymb;

        this.terminale = new ArrayList<String>();
        this.nichtTerminale = new ArrayList<String>();

        it = this.regeln.iterator();
        while (it.hasNext()) {
            aktR = it.next();
            if (!this.nichtTerminale.contains(aktR.getKopf())) {
                this.nichtTerminale.add(aktR.getKopf());
            }
        }

        it = this.regeln.iterator();
        while (it.hasNext()) {
            aktR = it.next();
            it2 = aktR.getNPunkt().iterator();
            while (it2.hasNext()) {
                aktSymb = it2.next();
                if (!this.nichtTerminale.contains(aktSymb)
                    && !this.terminale.contains(aktSymb)) {
                    this.terminale.add(aktSymb);
                }
            }
        }
    }

    /**
     * Liest eine Grammatik aus der angegebenen Textdatei und erzeugt eine
     * entsprechende Struktur in <code>this</code>. Dabei wird das Feld
     * <code>this.regeln</code> mit den Regeln aus der Grammatikdatei
     * initialisiert, nicht jedoch die Felder <code>this.terminale</code>
     * und <code>this.nichtTerminale</code>. Letztere m�ssen durch
     * nachtr�glichen Aufruf von <code>this.extrahiereSymbole</code>
     * initialisiert werden.
     *
     * @param name  Der Name der Grammatikdatei.
     */
    private void liesGrammatik(final String name) {
        Iterator<String> it;
        String aktR;
        ArrayList<String> stringRegeln = new ArrayList<String>();
        EarleyRegel aktRegel;
        ArrayList<String> rechts;
        String links;

        try {
            RandomAccessFile file = new RandomAccessFile(name, "r");
            while (file.getFilePointer() < file.length()) {
                stringRegeln.add(file.readLine());
            }
            file.close();
        } catch (final IOException e) {
            System.err.println(e);
        }

        this.regeln = new ArrayList<EarleyRegel>();

        it = stringRegeln.iterator();
        while (it.hasNext()) {
            aktR = it.next();
            rechts = SonstMeth.zerlege(aktR, Konstanten.TRENN_GR);
            links = (String) rechts.get(0);
            rechts.remove(0);
            aktRegel = new EarleyRegel(links, rechts);
            regeln.add(aktRegel);
        }
    }

    /**
     * Textausgabe einer Grammatik.
     *
     * @return  Die Textausgabe.
     */
    public String toString() {
        String s = "";
        Iterator<EarleyRegel> it = this.regeln.iterator();
        Iterator<String> it2;
       
        s = s + "Regeln:\n\n";
        while (it.hasNext()) {
            s = s + ((EarleyRegel) it.next()).toSimpleString() + "\n";
        }

        s = s + "\nNichtterminale: ";
        it2 = this.nichtTerminale.iterator();
        while (it2.hasNext()) {
            String zwisch = it2.next();
            s = s + zwisch;
            if (zwisch.equals(this.strSymb())) {
                s = s + " (Startsymbol)";
            }
            if (it2.hasNext()) {
                s = s + ", " + Konstanten.TRENN_EING;
            }
        }

        s = s + "\nTerminale:      ";
        it2 = this.terminale.iterator();
        while (it2.hasNext()) {
            s = s + it2.next();
            if (it2.hasNext()) {
                s = s + ", " + Konstanten.TRENN_EING;
            }
        }

        return s;
    }

    /**
     * Gibt die Nummer des zu <code>symb</code> geh�renden Symbols zur�ck.
     * Dabei gilt, dass f�r jedes Symbol aus "Nichtterminale U Terminale" genau
     * eine positive Integer-Zahl zur�ckgegeben wird und f�r alle paarweise
     * verschiedenen Symbole auch unterschiedliche Zahlen zur�ckgegeben werden.
     * <P>
     * Falls Das �bergebene Symbol nicht in der Grammatik existiert, wird -1
     * zur�ckgegeben.
     *
     * @param symb  Das Symbol, dessen Nummer berechnet werden soll.
     *
     * @return  Die Nummer des Symbols.
     */
    public int symbNum(final String symb) {
        Iterator<String> it1 = this.nichtTerminale.iterator();
        Iterator<String> it2 = this.terminale.iterator();
        int i = 0;

        while (it1.hasNext()) {
            if (it1.next().equals(symb)) {
                return i;
            }
            i++;
        }

        while (it2.hasNext()) {
            if (it2.next().equals(symb)) {
                return i;
            }
            i++;
        }

        return -1;
    }

    /**
     * Gibt das Startsymbol zur�ck.
     *
     * @return  Das Startsymbol.
     */
    public String strSymb() {
        return (String) this.nichtTerminale.get(0);
    }

    /**
     * Ob ein Symbol ein Terminalsymbol ist.
     *
     * @param symb  Das zu �berpr�fende Symbol.
     *
     * @return  Ob Terminalsymbol.
     */
    public boolean istTerminal(final String symb) {
        Iterator<String> it = this.terminale.iterator();
        while (it.hasNext()) {
            if (it.next().equals(symb)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Ob ein Symbol ein Nichtterminalsymbol ist.
     *
     * @param symb  Das zu �berpr�fende Symbol.
     *
     * @return  Ob Nichtterminalsymbol.
     */
    public boolean istNTerm(final String symb) {
        return !this.istTerminal(symb);
    }

    /**
     * @return Returns the nichtTerminale.
     */
    public ArrayList<String> getNichtTerminale() {
        return this.nichtTerminale;
    }

    /**
     * @return Returns the regeln.
     */
    public ArrayList<EarleyRegel> getRegeln() {
        return this.regeln;
    }

    /**
     * @return Returns the terminale.
     */
    public ArrayList<String> getTerminale() {
        return this.terminale;
    }

    /**
     * Verschiebt den Punkt einer Regel um eins nach rechts.
     *
     * @param r  Die Regel, deren Punkt verschoben werden soll.
     */
    public void verschPunktR(final EarleyRegel r) {
        r.verschPunktR();
    }

    /**
     * Setzt alle Regeln (ihre Punkte) auf den Anfangszustand zur�ck.
     */
    public void init() {
        Iterator<EarleyRegel> it = this.regeln.iterator();
        EarleyRegel aktR;

        while (it.hasNext()) {
            aktR = (EarleyRegel) it.next();
            aktR.init();
        }
    }
}
TOP

Related Classes of fmg.fmg8.earleyErkenner.EarleyGrammatik

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.