2016-11-06 40 views
1

我對Haskell相當新,我試圖做一個簡單的解析器,並使用Parsec模塊。我的解析器的語法是:如何在解析Haskell時正確區分詞幹字符和文字字符

data Frag 
    = Lt String 
    | St 
    deriving (Eq, Show) 

type Template = [Frag] 

type FileT = Template 
type CommandT = Template 

data Rule 
    = Rule [FileT] [FileT] [CommandT] 
    deriving (Eq, Show) 

type Makefile = [Rule] 

我已經實現一路下跌至片段(這將是字符集)。下面是我如何試圖處理文本字符的文檔片斷,我不知道如何處理,雖然乾的字符:

template :: Parser [Frag] 
template = 
    do result <- many frag 
     return result 
frag :: Parser Frag 
frag = do Lt x <- (many (noneOf ['\n','\t','\r',':','.'])) 
      return x 

但我發現了這個錯誤,我不知道爲什麼:

Parser\Impl.hs:72:11: error: 
    • Couldn't match expected type ‘[Char]’ with actual type ‘Frag’ 
    • In the pattern: Lt x 
     In a stmt of a 'do' block: 
     Lt x <- (many (noneOf ['\n', '\t', '\r', ':', ....])) 
     In the expression: 
     do { Lt x <- (many (noneOf ['\n', '\t', ....])); 
      return x } 

Parser\Impl.hs:73:11: error: 
    • Couldn't match type ‘[Char]’ with ‘Frag’ 
     Expected type: Text.Parsec.Prim.ParsecT 
         String() Data.Functor.Identity.Identity Frag 
     Actual type: Text.Parsec.Prim.ParsecT 
         String() Data.Functor.Identity.Identity String 
    • In a stmt of a 'do' block: return x 
     In the expression: 
     do { Lt x <- (many (noneOf ['\n', '\t', ....])); 
      return x } 
     In an equation for ‘frag’: 
      frag 
      = do { Lt x <- (many (noneOf ['\n', ....])); 
        return x } 

輸入:

"aaa : bbb ccc" 
"\:aaa : \%bbb \\ccc 

輸出:

[["aaa"] , ["bbb"] , ["ccc"]] 
[[":aaa"] , ["%bbb"] , ["\ccc"]]  
+0

什麼是幹字符?你想要解析的語法是什麼?如果你提供了一個示例輸入和你試圖獲得的輸出,這可能會非常有幫助。 –

+0

完成。字符如%:\ n \ t \ r被排除,但是如果字符串包含'\',它會使其成爲字面值(例如「\%」 - >「%」,而「%」 - >「」)。 –

回答

1
frag :: Parser Frag 
frag = do Lt x <- (many (noneOf ['\n','\t','\r',':','.'])) 
      return x 

many,在這裏,產生了Parser [Char]。您試圖將[Char]結果與Frag模式匹配,導致類型錯誤。相反,你想...

frag :: Parser Frag 
frag = do x <- (many (noneOf ['\n','\t','\r',':','.'])) 
      return (Lt x) 

...或者乾脆:

frag :: Parser Frag 
frag = fmap Lt (many (noneOf ['\n','\t','\r',':','.'])) 

PS:在你的其他定義...

template :: Parser [Frag] 
template = 
    do result <- many frag 
     return result 

...只爲結合result立即使用return就是多餘的。你可以這樣寫:

template :: Parser [Frag] 
template = many frag 

P.P.S:正如你已經注意到了(也許如你預期),many frag是不夠的,做你想要什麼。您將需要以某種方式指定如何劃分您的分段。

+0

謝謝!它清除了錯誤...現在我的程序永遠循環。我懷疑有很多(noneOf ...聲明 –

+0

@NándorZ.Papp更確切地說,我相信當你嘗試使用'many frag'時,問題就會體現出來,而不是一個循環,在這裏它會用'Exception:Text'來保存。 ParserCombinators.Parsec.Prim.many:combinator'many'被應用於一個接受空字符串的解析器,'',這是有道理的。如果你想分解輸入字符串的幾個部分,你需要指定某種'frag'解析器中的分隔符或長度限制。 – duplode

相關問題