2012-05-09 10 views
6

Estoy tratando de entender a Alex y los lexers en general, pero estoy teniendo problemas para ejecutar mi Lexer.Haskell Alex - error en la plantilla del contenedor

Escribí lexers en envoltorios "básicos" y "posn" pero no pude en el envoltorio "monad". Creo que tengo que usar el contenedor monad porque necesito recopilar cadenas y posiciones de tokens en la entrada. También necesito múltiples estados. Por ahora estoy tratando de ejecutar este sencillo exmaple:

{ 
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 
} 

Mis acciones son undefined por ahora. Cuando intento compilar, lo estoy consiguiendo este error:

➜ 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)' 

También estoy consiguiendo varios errores cuando intento compilar ejemplos en github repo de Alex, podría estar relacionado con un conflicto de versiones? Instalé alex de cabal con ghc 7.0.4. ¿Algunas ideas?

Respuesta

7

Esto parece un error en Alex 3.0.1. Funciona bien en la versión 2.3.3 después de tratar con algunos otros problemas no relacionados en su código . El problema es que esta línea en el código generado:

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

Siguiendo los tipos en el código generado, parece que esta función debe tener el tipo AlexInput -> AlexInput, pero AlexInput, obviamente, no puede ser a la vez una 3-tupla y una 4-tupla.

Esto probablemente ocurrió porque la definición de AlexInput se cambió entre las dos versiones.

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

De lo que puedo decir, el código correcto debe ser

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

y de forma manual haciendo de este cambio en el código generado hace que sea compilar después de tratar con los otros temas.

Sin embargo, a menos que necesite algo de la versión 3.0.1, le sugiero que cambie la versión hasta que se solucione, ya que mantener parches contra el código generado suele ser más problemático de lo que vale.

Su código no se encuentra una instancia de ShowLexeme y también se está llamando return en alexMonadScan, que ya está en la mónada Alex.

+0

Gracias! ¿Debo abrir un problema en su repositorio de GitHub? – sinan

+0

@sinan: Sí, eso probablemente sería una buena idea. – hammar

Cuestiones relacionadas