Parser und Übersetzer

Basisklassen ParserFunctions, Parser, Compiler

 aufwärts

Die abstrakte Klasse Parser dient als Basisklasse für einen konkreten Recursive-Descent-Parser. Sie greift ihrerseits zurück auf eine abstrakte Klasse ParserFunctions zurück. Wenn es später nicht nur um das Parsen geht, sondern über die reine Syntaxprüfung hinaus um das Übersetzen, kommt als Basisklasse für konkrete Übersetzer noch die abstrakte Klasse Compiler hinzu (Bild 1).

 

Bild 1: Klassenhierarchie von Parsern und Compilern
Bild 1: Klassenhierarchie von Parsern und Compilern

Klasse ParserFunctions

In der Klasse ParserFunctions befinden sich die globalen Variablen inputstring, haserrors, errormessage und errorposition sowie grundlegende Funktionen zur Abarbeitung des Eingabe­wortes.

 

/** Grundlegende Funktionen für Parser und Compiler
 */
public abstract class ParserFunctions
{
    protected String inputstring;
    public boolean haserrors;
    public String errormessage;
    public int errorposition;
    protected static final String DIGIT="0123456789";

    // liefert true, wenn das Eingabewort leer ist
    protected boolean inputEmpty()
    {
        return inputstring.length()==0;
    }

    // liefert true, wenn das Eingabewort mit String x beginnt
    protected boolean comes(String x)
    {
        return inputstring.startsWith(x);
    }

    // liefert das erste Zeichen des Eingabestrings
    protected String lookahead()
    {
        return inputstring.substring(0, 1);
    }

    // entfernt erstes Zeichen des Eingabewortes und liefert es zurück
    protected String getSymbol()
    {
        String d=lookahead();
        consume(1);
        return d;
    }

    // entfernt k Zeichen am Anfang des Eingabewortes
    protected void consume(int k)
    {
        inputstring=inputstring.substring(k);
    }

    // entfernt String x am Anfang des Eingabewortes
    protected void consume(String x)
    {
        consume(x.length());    // Präfix x wird konsumiert
    }

    // liefert true, wenn das Eingabewort mit irgendeinem
    // Zeichen beginnt, das in String x enthalten ist
    protected boolean comesAnyOf(String x)
    {
        if (inputEmpty())
            return false;
        String y=lookahead();  // erstes Zeichen des Eingabewortes
        return x.indexOf(y)>=0;
    }

    // liefert true, wenn das Eingabewort mit einer Ziffer beginnt
    protected boolean comesDigit()
    {
        return comesAnyOf(DIGIT);
    }

    // wenn das Eingabewort mit String x beginnt, wird
    // der String x am Anfang des Eingabewortes entfernt
    // und true zurückgegeben
    protected boolean trymatch(String x)
    {
        if (comes(x))
        {
            consume(x);
            return true;
        }
        else
            return false;
    }

    // wenn das Eingabewort mit String x beginnt, wird
    // der String x am Anfang des Eingabewortes entfernt;
    // anderenfalls wird eine Exception ausgelöst
    protected void match(String x)
    {
        if (!trymatch(x))
            throw new RuntimeException("Erwartet: "+x);
    }

    // zeigt die Position eines Syntaxfehlers an
    public String errorPointer()
    {
        return fill("-", errorposition)+"^";
    }

    // liefert den String x hoch k
    private String fill(String x, int k)
    {
        String s="";
        for (int i=0; i<k; i++)
            s+=x;
        return s;
    }

}    // end class ParserFunctions

Klasse Parser

In der Klasse Parser befindet sich die public-Methode parse(String x). Diese übernimmt das Eingabewort x, weist es der globalen Variablen inputstring zu und ruft die Methode startSymbol() auf. Die Methode startSymbol() ist abstrakt; sie muss in dem jeweiligen konkreten Parser, der von der abstrakten Klasse Parser abgeleitet wird, implementiert werden. Darüber hinaus fängt die Methode parse jegliche Fehler auf, die beim Parsen des Eingabe­wortes aufgrund von Syntax­fehlern möglicher­weise ausgelöst werden.

 

/** Basisklasse für einen Parser
 */
public abstract class Parser extends ParserFunctions
{

    // Aufruf des Startsymbols; muss in der abgeleiteten
    // Klasse implementiert werden
    protected abstract void startSymbol();

    // übernimmt einen Eingabestring und ruft das Startsymbol
    // der Grammatik auf; erzeugt ggf. Fehlermeldung und
    // Position des Fehlers im Eingabestring
    public void parse(String x)
    {
        inputstring=x;
        haserrors=false;
        errormessage="ok";
        try
        {
            startSymbol();
            if (!inputEmpty())
                throw new RuntimeException("Zuviele Zeichen: "+inputstring);
        }
        catch (RuntimeException e)
        {
            haserrors=true;
            errormessage=e.getMessage();
        }
        errorposition=x.length()-inputstring.length();
    }

}    // end class Parser

Compiler

Die Klasse Compiler ist genauso aufgebaut wie die Klasse Parser. Der Unterschied besteht darin, dass der Aufruf des Startsymbols jetzt einen Wert vom Typ Type zurückliefert. Dieser Wert stellt das Ergebnis der Übersetzung dar.

 

/** Basisklasse für einen Compiler
 */
public abstract class Compiler<Type> extends ParserFunctions
{

    // Aufruf des Startsymbols; muss in der abgeleiteten
    // Klasse implementiert werden
    protected abstract Type startSymbol();

    // übernimmt einen Eingabestring und ruft das Startsymbol
    // der Grammatik auf; erzeugt ggf. Fehlermeldung und
    // Position des Fehlers im Eingabestring
    public Type compile(String x)
    {
        inputstring=x;
        Type result=null;
        haserrors=false;
        errormessage="ok";
        try
        {
            result=startSymbol();
            if (!inputEmpty())
                throw new RuntimeException("Zuviele Zeichen: "+inputstring);
        }
        catch (RuntimeException e)
        {
            haserrors=true;
            errormessage=e.getMessage();
        }
        errorposition=x.length()-inputstring.length();
        return result;
    }

}    // end class Compiler

 

up

 

homeH.W. Lang   Hochschule Flensburg   lang@hs-flensburg.de   Impressum   Datenschutz   ©   Created: 06.11.2009   Updated: 10.06.2018
Valid HTML 4.01 Transitional