6

私は、Haskellのようなレイアウト構文を使用して非常に単純な関数型言語を解析するためにTrifectaを実験しています。Trifecta自体に紹介資料が見つからなかったため、HaddockのドキュメントとParsecでの経験に取り組んでいます。

私が抱えている問題は、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

次のテキストを次のように解析しようとしていますtest

f x = x y a b c -- 1
  where         -- 2
    y = d       -- 3
g x = z         -- 4

しかし、この解析エラーで失敗します:

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

しかし、2行目と3行目をコメントアウトすると、機能します。

では、2行目と3行目を含めても解析するにはどうすればよいですか?

4

1 に答える 1

6

LayoutTrifectaのサポートにはいくつかのバグがあります。Scalaの実装からいくつかの修正を移植する必要があります。

特に、行頭チェックを無効にする必要があるものがいくつかありますが、無効にしないため、エラーが発生している場所で自動セミコロン挿入を実行しようとしました。

私はそれを私の別のコードベースから移植しました。それはわずかに異なる仮定を行い、trifectaとはわずかに異なる不変条件を提供しました。

これは実際には、現在githubのマスターブランチにない理由の大部分です。

新しいparsersベースのAPIを使用するように修正し、それらの変更を移植することは、0.90を出荷する前に行う必要がある最後の主要なことです。

その間、私はそれに頼りません。謝罪いたします。

安定したらすぐにこの応答を更新します。

于 2012-09-11T21:56:56.517 に答える