/* * Basisgrammatik für MML (bzw. MMS) * * $Autor:$ * $Log: MMS-bisonin.txt,v $ * Revision 1.3 2000/05/03 09:49:26 lammers * Kleinere Anpassungen. TRUE und FALSE als Token entfernt. * Datei sinnvoller umbenannt. * * Revision 1.2 2000/04/18 09:58:03 lammers * Nach der ersten Besprechung der Sprachelemente * * Revision 1.1 2000/04/11 10:35:48 lammers * Initial revision * * * Alte Anmerkungen vor der Versionierung mit rcs: * * Änderungen zu 1.0: * - Neue Terminalsymbole IN, OUT, * - weitere Alternativen in der Regel * 'Prozeduraufruf' für IN und OUT * * Version 1.0 * Stand: 21.4.98 * Autor: Dietmar Lammers * * ---------------------------------------------------------------- * * MML-Kommentare sind auf dieser Ebene schon vom Lex. Analysator * eleminiert. Sie beginnen und enden mit '**'. * * Kommentare in dieser Datei sind wie in der Sprache C definiert. * * Zur Schreibweise: Leerzeichen und Zeilenumbrüche dürfen in einer * Regel vorkommen. Zu jeder Regel gibt es einen Kommentar, der * Erläuterungen gibt und ggf. die informelle Semantik festlegt. * * Nichtterminalsymbole enthalten mindestens einen * Kleinbuchstaben. Terminalsymbole sind in GROSSBUCHSTABEN angegeben, * oder sind einbuchstabig und in '' eingeschlossen. Für alle * Terminalsymbole müssen Tokenklassen vorhanden sein. (Insbesondere * wird für jedes Schlüsselwort eine eigenen Tokenklasse verwendet - * das macht das Parsen wesentlich einfacher). Neben den * einbuchstabigen verwenden also die Tokenklassen: * * PROGRAM IDENTIFIKATOR BEGIN END VAR INTEGER REAL BOOLEAN ARRAY OF * PROC ASSIGNOP GOTO WHILE DO OD UNARYLOGOP BINARYLOGOP * VERGLEICHSOP UNARYARITHOP BINARYARITHOP IF THEN ELSE FI IN OUT * * MML-Kommentare sind auf dieser Ebene schon vom Lex. Analysator * eleminiert. Sie beginnen und enden mit '**'. */ Programm ::= PROGRAM Programmname '=' Block '.' /* Program ist das Startsymbol. Ein Wort in MML ist genau ein (benanntes) Programm. Bei Aufruf des Programms werden die Anweisungen aus dem Block einmalig ausgeführt. */ Programmname ::= IDENTIFIKATOR /* ein Programmname ist ein normaler Identifikator */ Block ::= BEGIN Deklarationsteil Anweisungsteil END | BEGIN Anweisungsteil END /* Ein Block besteht aus einer optionalen Folge von Deklarationen, und einer Folge von Anweisungen. Die Anweisungen werden bei Ausführung in der Reihenfolge des Auftretens ausgeführt (sofern nicht gesprungen oder verzeigt wird) */ Deklarationsteil ::= Variablendeklarationen | Prozedurdeklarationen | Variablendeklarationen Prozedurdeklarationen /* Im Deklarationsteil kommen zuerst die Variablendeklarationen, dann die Prozedurdeklaratioen. Je einer kann auch wegfallen. */ Variablendeklarationen ::= Variablendeklaration ';' | Variablendeklaration ';' Variablendeklarationen /* Ein oder mehrere Variablendeklarationen werden mit Semikolon getrennt bzw. abgeschlossen */ Variablendeklaration : VAR Variablenidentifikator ':' Typ /* Für jede Variable ist bei der Deklaration die Angabe von 'var' und die Definition des Typs notwendig. */ Variablenidentifikator ::= IDENTIFIKATOR /* ein Variablenidentifikator ist ein normaler Identifikator */ Typ ::= Einfachtyp | Strukturtyp /* Eine Typangabe kann einen einfachen oder einen strukturierten Typ deklarieren */ Einfachtyp ::= INTEGER | REAL | BOOLEAN /* Ein einfacher Typ ist einer der Basistypen. Insbesondere ist ein Label von keinem Typ, damit sind formale Sprünge syntaktisch eleminiert */ Strukturtyp ::= ARRAY '[' Feldgrenzen ']' OF Einfachtyp /* Einziger strukturierter Typ ist das Feld (engl. array). Damit ist MML natürlich nicht sehr komfortabel: weitere Strukturen und Verweistypen fehlen für eine moderne Sprache! */ Feldgrenzen ::= Untergrenze ':' Obergrenze | Untergrenze ':' Obergrenze ',' Feldgrenzen /* Pro Dimension des Feldes muß eine obere und untere Grenze angegeben werden. */ Untergrenze ::= arithmetischerAusdruck ; Obergrenze ::= arithmetischerAusdruck ; /* Die Feldgrenzen sind arithmetische Ausdrücke, hier dürfen aber nur INTEGER-Type auftreten. Das muss die semantischen Analyse zur Laufzeit sicherstellen! */ Prozedurdeklarationen ::= Prozedurdeklaration ';' | Prozedurdeklaration ';' Prozedurdeklarationen /* Ein- oder mehrerer Prozedurdeklarationen */ Prozedurdeklaration ::= PROC Prozedurname Parameterliste '=' Block /* Fast wie Programm, aber mit einer Parameterliste zur Übergabe von aktuellen Werten */ Prozedurname ::= IDENTIFIKATOR /* Ein Prozedurname ist ein normaler Identifikator */ Parameterliste ::= '(' ')' | '(' formaleParameterfolge ')' /* Die Parameterliste kann auch leer sein */ formaleParameterfolge ::= IDENTIFIKATOR ':' Parametertyp | IDENTIFIKATOR ':' Parametertyp ',' formaleParameterfolge /* Mindestens ein Name mit zugehörigem erwartetem Typ */ Parametertyp ::= Typ | PROC /* Für Prozedurparameter kann nur das Schlüsselwort PROC deklariert werden */ /* -------- hier kommen die eigentlichen Anweisungen ------- */ Anweisungsteil ::= Anweisung | Anweisung ';' Anweisungsteil /* Eine oder mehrere, durch Semikolon getrennte Anweisungen. Sie werden hintereinander ausgeführt. */ Anweisung ::= unmarkierteAnweisung | markierteAnweisung /* Mit oder ohne Label */ markierteAnweisung ::= Marke ':' unmarkierteAnweisung /* Das Label für eine Anweisung, um ggf. hierhin zu springen */ Marke ::= IDENTIFIKATOR /* Ein Label ist ein einfacher Indetifikator */ unmarkierteAnweisung ::= unbedingteAnweisung | bedingteAnweisung /* Ggf. hängt die Ausführung von Bedingungen ab. */ unbedingteAnweisung ::= Wertzuweisung | Sprunganweisung | Prozeduraufruf | Eingabe | Ausgabe | Wiederholungsanweisung | Block /* Das sind alle einfachen Anweisungen. Block zuzulassen ist nicht ganz trivial, und sollte ggf. semantisch wie eine namenlose Prozedur gehandhabt werden. */ Wertzuweisung ::= Variable ASSIGNOP Ausdruck /* (ASSIGNOP ist ':=') Der Ausdruck wird ausgewertet, und der resultierende Wert der Varablen zugewiesen. */ Sprunganweisung ::= GOTO Marke /* Es wird zum entsprechenden Label gesprungen und an der Stelle weiter ausgewertet. Achtung auf Bindungen! */ Prozeduraufruf ::= Prozedurname Argumentliste /* Die Argumentliste wird ausgewertetet und die entspr. Prozedur mit den Werten der Argumentliste für die formalen Parameter ausgewertet. Felder werden call-by-reference übergeben, alle anderen Werte call-by-value ?? und Prozeduren/Label als Parameter ?? */ Eingabe ::= IN Variable /* Es wird ein Wert entsprechend des Typs der Variable eingelesen, und als Wert der Variable abgelegt */ Ausgabe ::= OUT aktuelleParameterfolge /* Die Parameter werden ausgewertet und ausgegeben. Nur einfachen Typen (auch Feldelemente) sind erlaubt. */ Wiederholungsanweisung ::= WHILE Bedingung DO Anweisungsteil OD /* Solange die Auswertung der Bedingung den Wert TRUE ergibt, wird der Anweisungsteil ausgeführt. */ Ausdruck ::= logischerAusdruck | arithmetischerAusdruck /* einfache Ausdrücke */ logischerAusdruck ::= BOOLEAN | Variable | '(' UNARYLOGOP logischerAusdruck ')' | '(' logischerAusdruck BINARYLOGOP logischerAusdruck ')' | '(' logischerAusdruck ')' | '(' arithmetischerAusdruck VERGLEICHSOP arithmetischerAusdruck ')' /* Die Unterausdrücke werden evaluiert, und der sich ergebende Wahrheitswert zurückgegeben. (Das muß durch Zahlen modelliert werden!) */ arithmetischerAusdruck ::= | INTEGER | REAL | Variable | '(' UNARYARITHOP arithmetischerAusdruck ')' | '(' arithmetischerAusdruck BINARYARITHOP arithmetischerAusdruck ')' | '(' arithmetischerAusdruck ')' /* Die Unterausdrücke werden evaluiert, und der sich ergebende Wahrheitswert zurückgegeben. Diese Syntax schreibt vollständige Klammerung vor. */ Variable ::= Variablenidentifikator | Variablenidentifikator '[' Indizes ']' /* Als Variable sind auch Arrayfelder erlaubt. Referenziert wird dann das Feld mit entsprechend ausgewerteten Indizes. */ Indizes ::= arithmetischerAusdruck | arithmetischerAusdruck ',' Indizes /* Auch hier können REAL-Werte eintreten (vgf. Feldgrenzen) In der semantischen Analyse muss sichergestellt werden, dass nur INTEGER-Typen hier auftreten */ Argumentliste ::= '(' ')' | '(' aktuelleParameterfolge ')' /* Kann auch leer sein, aber Klammern müssen angegeben werden */ aktuelleParameterfolge ::= aktuellerParameter | aktuellerParameter ',' aktuelleParameterfolge /* Ein oder mehrerer Parameterwerte, durch Komma getrennt. Ausgewertet wird in der Reihenfolge des Auftretens */ aktuellerParameter ::= Ausdruck | Prozedurname /* Entspr. den bei der Deklaration festgelegten Typen */ Bedingung ::= logischerAusdruck /* Eine Beginung ist einfach ein logischer Ausdruck */ bedingteAnweisung ::= IF Bedingung THEN Anweisungsteil ELSE Anweisungsteil FI /* Die Bedingung wird ausgewertet. Ist die TRUE, wird der dem THEN folgende Teil der Anweisung ausgeführt, ist sie FALSE, der dem ELSE folgende. Andere Fälle sind als Fehler zu behandeln! */