2012-05-09 31 views
6

Tôi đang cố gắng hiểu Alex và lexers nói chung nhưng tôi gặp khó khăn để chạy lexer của tôi.Haskell Alex - lỗi trong mẫu wrapper

Tôi đã viết lexers trong trình bao bọc "cơ bản" và "posn" nhưng tôi không thể trong trình bao bọc "đơn nguyên". Tôi nghĩ rằng tôi phải sử dụng monad wrapper vì tôi cần phải thu thập các chuỗi và vị trí mã thông báo trong đầu vào. Tôi cũng cần nhiều tiểu bang. Hiện tại, tôi đang cố chạy exmaple đơn giản này:

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

Hành động của tôi là undefined hiện tại. Khi tôi cố gắng biên dịch nó, tôi nhận được lỗi này:

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

Tôi cũng nhận lỗi khác nhau khi tôi cố gắng biên dịch ví dụ trong repo github của Alex, nó có thể liên quan với một phiên bản không phù hợp? Tôi đã cài đặt alex từ cabal với ghc 7.0.4. Bất kỳ ý tưởng?

Trả lời

7

Điều này giống như một lỗi trong Alex 3.0.1. Nó hoạt động tốt trong phiên bản 2.3.3 sau khi xử lý một số vấn đề không liên quan khác trong mã của bạn . Vấn đề là dòng này trong mã được tạo:

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

Bằng cách làm theo các loại trong các mã được tạo ra, nó có vẻ như chức năng này nên có các loại AlexInput -> AlexInput, nhưng AlexInput rõ ràng là không thể cả 3 tuple và một 4-tuple.

Điều này có thể xảy ra do định nghĩa của AlexInput đã được thay đổi giữa hai phiên bản.

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

Từ những gì tôi có thể nói, các mã chính xác nên được

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

và tự làm cho sự thay đổi này trong các mã được tạo ra làm cho nó biên dịch sau khi đối phó với các vấn đề khác. Tuy nhiên, trừ khi bạn cần một cái gì đó từ 3.0.1, tôi khuyên bạn nên hạ cấp cho đến khi điều này được khắc phục, vì việc phải duy trì các bản vá lỗi chống lại mã được tạo ra thường khó khăn hơn giá trị của nó.

Mã của bạn thiếu một trường hợp Show cho Lexeme và bạn cũng đang gọi điện thoại return trên alexMonadScan, đó là đã có trong Alex đơn nguyên.

+0

Cảm ơn! Tôi có nên mở một vấn đề trong repo GitHub của nó? – sinan

+0

@sinan: Vâng, đó có thể là một ý tưởng hay. – hammar

Các vấn đề liên quan