我真的很難分析Haskell,但它最有意義。Parsec:處理重疊解析器
我正在建立一個模板化程序主要是爲了學習解析更好;模板可以通過{{ value }}
表示法插值。
這是我目前的解析器,
data Template a = Template [Either String a]
data Directive = Directive String
templateFromFile :: FilePath -> IO (Either ParseError (Template Directive))
templateFromFile = parseFromFile templateParser
templateParser :: Parser (Template Directive)
templateParser = do
tmp <- template
eof
return tmp
template :: Parser (Template Directive)
template = Template <$> many (dir <|> txt)
where
dir = Right <$> directive
txt = Left <$> many1 (anyChar <* notFollowedBy directive)
directive :: Parser Directive
directive = do
_ <- string "{{"
txt <- manyTill anyChar (string "}}")
return $ Directive txt
然後我在文件上是這樣運行:
{{ value }}
This is normal Text
{{ expression }}
當我運行使用templateFromFile "./template.txt"
這個我得到的錯誤:
Left "./template.txt" (line 5, column 17):
unexpected Directive " expression "
爲什麼會發生這種情況,我該如何解決?
我的基本理解是,many1 (anyChar <* notFollowedBy directive)
應抓住所有的字符,直到下一個指令的開始,然後應該失敗並返回字符列表直到該點;那麼 它應該回落到以前的many
,並應嘗試再次解析dir
並應成功;顯然還有其他事情正在發生。我是 在解析器大部分重疊時無法解析如何解析之間其他事情。
我很想知道如何更加地道地構建這些技巧,請讓我知道我是否以愚蠢的方式做事。乾杯!謝謝你的時間!
有道理;我怎樣才能最好地解決它做我期望的? –
'txt = many1(notFollowedBy directive *> anyChar)'是最簡單的修復方法,儘管它每個指令運行兩次'directive'。 –