使用Trifecta的布局解析器

Cac*_*tus 6 parsing haskell parser-combinators trifecta

我正在尝试使用Trifecta来解析一个非常简单的函数式语言,使用类似Haskell的布局语法.我正在处理Haddock文档和我对Parsec的经验,因为我找不到关于Trifecta本身的任何介绍性材料.

我遇到的问题是使用布局的东西,因为即使是Haddock文档也没有多大帮助.

给出以下代码:

import Text.Trifecta
import Text.Trifecta.Parser.Token.Style
import Text.Trifecta.Parser.Identifier.Style
import Text.Trifecta.Layout.Combinators
import Text.Trifecta.Language.Prim

import Control.Applicative
import Control.Monad.Trans
import Data.Maybe (fromMaybe)

import Data.HashSet as HashSet
import Data.ByteString.UTF8 as UTF8

-- Copypasta from Text.Trifecta.Parser.Identifier.Style
set :: [String] -> HashSet ByteString
set = HashSet.fromList . fmap UTF8.fromString

lang :: MonadParser m => LanguageDef m
lang = LanguageDef{ languageCommentStyle = haskellCommentStyle
                  , languageIdentifierStyle = emptyIdents{ styleReserved = set keywords }
                  , languageOperatorStyle = emptyOps{ styleReserved = set ops }
                  }
  where
    keywords = ["where"]
    ops = ["="]

data Def = Def ByteString [ByteString] [ByteString] [Def]
         deriving Show

instance MonadLanguage m => MonadLanguage (Layout m) where
    askLanguage = fmap liftLanguageDef $ lift askLanguage

def :: (MonadParser m) => Layout (Language m) Def
def = Def <$> identifier <*> vars <* reservedOp "=" <*> vars <*> laidout locals
  where
    vars = many identifier
    locals = fromMaybe [] <$> optional (reserved "where" *> defs)

defs :: (MonadParser m) => Layout (Language m) [Def]
defs = laidout (many def)

test :: String -> IO ()
test =  parseTest $ run $ defs <* eof
  where
    run p = runLanguage (fst <$> runLayout p defaultLayoutState) lang
Run Code Online (Sandbox Code Playgroud)

我正在尝试解析以下文本test:

f x = x y a b c -- 1
  where         -- 2
    y = d       -- 3
g x = z         -- 4
Run Code Online (Sandbox Code Playgroud)

但它失败了这个解析错误:

(interactive):4:2: error: expected: "=",
    identifier, letter or digit
g x = z         -- 4 
 ^      
Run Code Online (Sandbox Code Playgroud)

但如果我注释第2行和第3行,它就可以了.

那么即使包含第2行和第3行,如何解析呢?

Edw*_*ETT 6

Layout支持Trifecta 有一些错误.我需要从Scala实现中移除一些修复.

值得注意的是,有些事情需要禁用行检查的开始,否则它会尝试在您收到错误时执行自动分号插入.

我从我的另一个代码库中移植它,它做出了稍微不同的假设,并且提供了与trifecta稍微不同的不变量.

这实际上是它目前不在github上的主分支中的很大一部分原因.

修复它以使用新parsers的API,并移植这些更改是我需要做的最后一件事,才能发货0.90.

与此同时,我不会依赖它.我很抱歉.

我会在稳定后立即更新此响应.

  • 我们目前已从主流三连词中删除了布局解析器.但是,你有很好的时机.我正在打扫它,并希望更换它.=) (2认同)