2012-05-09 1 views
6

Я пытаюсь понять Алекса и лексеров вообще, но мне трудно запустить мой лексер.Haskell Alex - ошибка в шаблоне обертки

Я написал лексеры в обложках «basic» и «posn», но не смог в оболочке «monad». Я думаю, что мне нужно использовать обертку monad, потому что мне нужно собирать строки и позиции токенов во входных данных. Мне также нужны несколько состояний. Сейчас я пытаюсь запустить эту простую 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 
} 

Мои действия undefined сейчас. Когда я пытаюсь скомпилировать его, я получаю эту ошибку:

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

Я также получаю различные ошибки, когда я пытаюсь собрать примеры в GitHub репо Алекса, может ли это быть связано с несоответствием версии? Я установил alex из cabal с ghc 7.0.4. Есть идеи?

ответ

7

Это похоже на ошибку в Alex 3.0.1. Он отлично работает в версии 2.3.3 после рассмотрения некоторых других несвязанных проблем в вашем коде . Проблема эта строка в сгенерированном коде:

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

Следуя типы в сгенерированном коде, похоже, эта функция должна иметь тип AlexInput -> AlexInput, но AlexInput, очевидно, не может быть и 3-кортеж и 4-кортеж.

Возможно, это произошло потому, что было изменено определение AlexInput между двумя версиями.

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

Из того, что я могу сказать, правильный код должен быть

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

и вручную сделать это изменение сгенерированного кода делает его компилировать после контакта с другими вопросами.

Однако, если вам не требуется что-то из 3.0.1, я предлагаю понизить до тех пор, пока это не будет исправлено, поскольку наличие исправлений от сгенерированного кода обычно больше проблем, чем того стоит.

Ваш код отсутствует Show экземпляр для Lexeme и вы также призывают return на alexMonadScan, который уже в Alex монады.

+0

Спасибо! Должен ли я открыть проблему в репозитории GitHub? – sinan

+0

@sinan: Да, это, вероятно, будет хорошей идеей. – hammar

 Смежные вопросы

  • Нет связанных вопросов^_^