Inhalt | Einführung | Theorie | JavaCC | JavaCC in der Praxis

JavaCC


Tokentypen

In JavaCC gibt es vier verschiedene Tokentypen, die unterschiedliche Aufgaben erfüllen.

Aufbau einer Definitionsdatei

Für die Spezifikation eines Parsers reicht eine zentrale Definitionsdatei aus. Sie ist an der Endung *.jj erkennbar und besitzt folgenden Aufbau:
options {
    name = wert;
}

PARSER_BEGIN(name)

    package pfad;
    
    import pfad;
    
    public class name {
        ...
    }
PARSER_END(name)

Tokendefinition

Regeln

Jede Definitionsdatei kann mit einer "options" - Anweisung beginnen, welche optional ist. In ihr wird das globale Verhalten des Parsers festgelegt. In der Regel leisten die Standardeinstellungen gute Dienste, sodass auf den Teil verzichtet werden kann

Zwingend notwendig hingegen ist der darauf folgende Block, der mit "PARSER_BEGIN" eingeleitet und mit "PARSER_END" abgeschlossen wird. In ihm können zusätzliche, javaspezifische Anweisungen gemacht werden, die in den Parser übernommen werden. Obligatorisch ist dabei eine entsprechende Methode, die den Zugriff auf den Parser ermöglicht. In der Regel bedient man sich einer "static void main" - Methode, falls der Parser über die Kommandozeile aufrufbar sein soll.

Im Anschluss folgen noch die Tokendefinition, sowie die Ableitungsregeln, ohne die der Parser nicht sinnvoll einsetzbar wäre

Aufbau einer Grammatikdefinition

Der grundsätzliche Aufbau einer Grammatikregel in JavaCC ist nachfolgend definiert.

void metasymbol() 	 
{
  ... // Code der am Anfang der	Methode steht
}
{
    <Terminal>                     { ... }
|   <Terminal1> <Terminal2>        { ... }
| ( <Terminal1> | <Terminal2> )    { ... }
| [ <Terminal> ]                   { ... } 
| ( <Terminal> )?                  { ... }
| ( <Terminal> )+                  { ... }
| ( <Terminal> )*                  { ... }
}

Jedes Nichtterminalsymbol wird durch eine Javamethode repräsentiert. In ihr werden die Ableitungsregel beschrieben. Terminalsymbole, zuvor mit Hilfe von Token definiert, können hier ebenso zum Einsatz kommen, wie auch Nichtterminalsymbole. Letztere müssen als Javamethode realisiert werden und können entsprechend aufgerufen werden. Das eben gezeigte Beispiel entählt nur Terminalsymbole. Im Kapitel JavaCC in der Praxis, werden wir uns komplexeren Grammatikdefinitionen widmen

Der erste Block beinhaltet Javacode, der vor dem eigentlichen Ableitungsschritt ausgeführt werden soll. Hierzu zählen z.B. Variablendefinitionen, die dann im weiteren Verlauf genutzt werden können

Eine Besonderheit von JavaCC ist die Möglichkeit, Javacode in die Ableitungsregeln zu integrieren. Erreicht wird dies durch "{ ... }" Blöcke. Der darin enthaltene Code wird unmittelbar nach der jeweiligen Ableitungsregel ausgeführt.