{ module Main where import ExpAlex -- von alex erzeugt, enthält Definition für Token-Typ } -- Name der Parserfunktion %name gaeParse -- der Tokentyp, den wir benutzen (Ausgabe des Scanners) %tokentype {Token} -- Abkürzungen für die Grammatik (nur Terminale) %token num { NumVal $$ _ } id { Id $$ _ } '+' { Plus _ } '*' { Times _ } '(' { OpenB _ } ')' { CloseB _ } -- - { Minus } -- / { Div } -- die Zeichen sind beliebige Abkürzungen für Terminalsymbole -- z.B. das "(" steht in der Grammatik für das Token "OpenB" des Scanners -- Das $$ steht für den _Wert_ des Tokens, den man für den Aufbau des Syntaxbaums nutzt. -- Im Fall eines NumVal ist das hier der Zahlwert, für Bool der Wahrheitswert. -- Alle anderen Token besitzen keinen _besonderen_ Wert, sondern ihr Wert sind sie selbst. -- das "%%" muss hier stehen (analog zu yacc), es kennzeichnet den Start der Grammatik %% -- ein Nonterminal kann einen Rückgabetyp haben, der wie hier angegeben wird: Exp :: { ExpTree } -- danach folgen die Regeln aus der Grammatik, jede mit einer Rückgabe Exp : Exp '+' Term { AddNode $1 $3 } | Term { $1 } Term :: { ExpTree } Term : Term '*' Factor { MulNode $1 $3 } | Factor { $1 } Factor :: { ExpTree } Factor : '(' Exp ')' { $2 } | id { Var $1 } | num { Const $1 } -- in den geschweiften Klammern steht der Wert, den die linke Seite bei Anwendung der -- Regel erhält (also das, was zurückgegeben wird, ein Teilbaum). -- Dieser Wert wird abhängig von den Werten auf der rechten Seite definiert. -- Das Parse-Ergebnis ist am Ende der Wert, den das Startsymbol erhält. -- Für die Rückgabe definiert man (rekursive) Typen, die den Parse-Baum bilden. { -- hier fängt der Haskell-Code an: happyError, Typen für den Parsebaum und Hilfsfunktionen. -- muss definiert werden, außerdem polymorph sein (das geht nur mit "error") -- happyError :: [Token] -> a happyError [] = error "Parse-Fehler: unerwartetes Dateiende." happyError (x:xs) = error ("Parse-Fehler in Zeile " ++ show (tokenLine x) ++ ": Token " ++ show x) data ExpTree = Const Int | Var String | MulNode ExpTree ExpTree | AddNode ExpTree ExpTree deriving Show }