2012-05-09 13 views
6

Ich versuche, Alex und Lexer im Allgemeinen zu verstehen, aber ich habe Probleme, meinen Lexer zu laufen.Haskell Alex - Fehler in Wrapper-Vorlage

Ich schrieb Lexer in "Basic" und "POSN" Wrapper, aber ich konnte nicht in "Monad" Wrapper. Ich denke, ich muss monad Wrapper verwenden, weil ich Strings und Token-Positionen in der Eingabe sammeln muss. Ich brauche auch mehrere Zustände. Denn jetzt versuche ich, diese einfache exmaple auszuführen:

{ 
module Main (main) where 
} 

%wrapper "monad" 

$whitespace = [\ \b\t\n\f\v\r] 
$digit  = 0-9 
$alpha  = [a-zA-Z_] 
$upper  = [A-Z] 
$lower  = [a-z] 

@tidentifier = $upper($alpha|_|$digit)* 
@identifier = $lower($alpha|_|$digit)* 


tokens :- 

$whitespace+ ; 
$upper $alpha+ { typeId } 
$lower $alpha+ { id_ } 
$digit+ { int } 

{ 

data Lexeme = L AlexPosn LexemeClass String 

data LexemeClass 
     = TypeId String 
     | Id String 
     | Int Int 
     | EOF 
    deriving (Show, Eq) 

typeId :: AlexInput -> Int -> Alex Lexeme 
typeId = undefined 

id_ :: AlexInput -> Int -> Alex Lexeme 
id_ = undefined 

int :: AlexInput -> Int -> Alex Lexeme 
int = undefined 

alexEOF = return (L undefined EOF "") 

main :: IO() 
main = do 
    s <- getContents 
    let r = runAlex s $ do 
       return alexMonadScan 
    print r 
} 

Meine Handlungen undefined sind für jetzt. Wenn ich versuche, es zu kompilieren, erhalte ich diese Fehlermeldung:

➜ haskell ghc --make Tokens.hs 
[1 of 1] Compiling Main    (Tokens.hs, Tokens.o) 

templates/wrappers.hs:208:17: 
    Couldn't match expected type `(AlexPosn, Char, [Byte], String)' 
       with actual type `(t0, t1, t2)' 
    Expected type: AlexInput 
     Actual type: (t0, t1, t2) 
    In the return type of a call of `ignorePendingBytes' 
    In the first argument of `action', namely 
     `(ignorePendingBytes inp)' 

ich auch verschiedene Fehler bekommen, wenn ich versuche Beispiele in Alex 'GitHub Repo zu kompilieren, es mit einem Versionskonflikt in Verbindung stehen könnte? Ich habe Alex von cabal mit ghc 7.0.4 installiert. Irgendwelche Ideen?

Antwort

7

Das sieht aus wie ein Fehler in Alex 3.0.1. Es funktioniert gut in Version 2.3.3 nach dem Umgang mit einigen anderen nicht verwandten Probleme in Ihrem Code . Das Problem ist, diese Linie in den generierten Code:

ignorePendingBytes (p,c,ps,s) = (p,c,s) 

Indem Sie die Typen in den generierten Code, wie es scheint, diese Funktion den Typ AlexInput -> AlexInput haben sollte, aber AlexInput offensichtlich können nicht beide ein 3-Tupel sein und ein 4-Tupel.

Dies liegt wahrscheinlich daran, dass die Definition von AlexInput zwischen den beiden Versionen geändert wurde.

type AlexInput = (AlexPosn, Char, String)   -- v2.3.3 
type AlexInput = (AlexPosn, Char, [Byte], String) -- v3.0.1 

Von dem, was ich sagen kann, sollte der richtige Code

seine
ignorePendingBytes (p,c,ps,s) = (p,c,[],s) 

und manuell macht diese Änderung in dem generierten Code es nach dem Umgang mit den anderen Themen zusammenstellen läßt.

Wenn Sie jedoch nichts von 3.0.1 benötigen, empfehle ich ein Downgrade, bis dies behoben ist, da das Pflegen von Patches gegen generierten Code in der Regel schwieriger ist als es wert ist.

Ihr Code fehlt eine Show Instanz für Lexeme und Sie sind auch return auf alexMonadScan Aufruf, die bereits in der Alex Monade ist.

+0

Danke! Sollte ich ein Problem in seinem GitHub Repo öffnen? – sinan

+0

@sinan: Ja, das wäre wahrscheinlich eine gute Idee. – hammar