[Ebene höher] [Zurück] [Weiter] [Inhalt] [Seitenende]
Lucky kennt, im Unterschied zu Happy, keine newline-Tokens. Die einzige Möglichkeit, Zeileninformation anzubieten, liegt beim Benutzer. Da ein newline-Token Mechanismus, wie ihn der Happy verwendet, im Normalfall ohnehin Eingriffe des Benutzers erfordert (z.B. Kommentare), erscheint es doch sinnvoller Zeilen- (und Spalteninformation) direkt beim Scannen in die Tokens zu verpacken.
{
data Lexem = TVarid String
| TComma
type Line = Int
type Col = Int
type Token = (Lexem, Line, Col)
}
%tokentype { Token }
%token varid { (TVarid $$, _, _) }
',' { (TComma, _, _) }
%%
Jeder Parser muß schließlich eine Fehlerfunktion luckyError implementieren. Entdeckt der Parser einen Syntaxfehler, dann ruft er diese Funktion auf und übergibt ihr das erste Token der Restliste der Eingabetokens. Der head dieser Liste ist das Token, das den Syntaxfehler verursacht hat. D.h. also, das Token, welches nicht mehr - auch nach versuchtem backtracking - zur längstmöglichen Herleitung gepaßt hat.
luckyError :: String -> [ %tokentype ] -> a
Hierbei muß %tokentype durch die Angabe dieser Direktive ersetzt werden (s.o.). Das erste Argument von luckyError ist das erste Argument, das der Parserfunktion %name (bzw. luckyParser) übergeben wurde. Für obiges Beispiel könnte man z.B. die einfache Fehlerfunktion
luckyError :: String -> [Token] -> a
luckyError filename [] =
error (filename ++ ": Unexpected EOF!");
luckyError filename ((lexem,l,c):_) =
error (filename ++ ": (" ++ show l ++ "," ++ show c ++
") Syntaxerror on input " ++ show lexem)
angeben.
©1996,97,98 Norbert Klose (nklose@mail.com)