2012-09-11 3 views
6

Ich experimentiere mit Trifecta, um eine sehr einfache funktionale Sprache mit Haskell-ähnlicher Layout-Syntax zu analysieren. Ich arbeite mit den Haddock-Dokumenten und meiner Erfahrung mit Parsec zusammen, weil ich kein einleitendes Material über Trifecta selbst finden konnte.Verwenden von Trifectas Layout-Parser

Das Problem, das ich habe, ist mit dem Layout-Zeug, da nicht einmal die Haddock-Dokumentation viel helfen.

mit dem folgenden Code:

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 

Ich versuche, den folgenden Text mit test zu analysieren:

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

aber es funktioniert nicht mit diesem Parser-Fehler:

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

aber wenn ich die Zeilen 2 und 3 kommentiere, funktioniert es.

Also wie mache ich es parse selbst wenn Zeilen 2 und 3 enthalten?

Antwort

6

Es gibt ein paar Bugs in der Layout Unterstützung für Trifecta. Ich muss einige Korrekturen von der Scala-Implementierung zurückgeben.

Vor allem ein paar Dinge müssen deaktivieren Sie den Start der Zeile zu überprüfen, dass nicht, so dass es versucht, automatische Semikolon einfügen, wo Sie den Fehler bekommen.

Ich portierte es von einer anderen Codebasis von mir, die etwas andere Annahmen machte und geringfügig andere Invarianten als Trifecta anbietet.

Dies ist eigentlich ein großer Teil davon, warum es derzeit nicht im Master-Zweig auf GitHub ist.

Es zu beheben, um die neue parsers -basierte API zu verwenden und diese Änderungen zu portieren, ist die letzte wichtige Sache, die ich tun muss, bevor ich 0.90 versenden kann.

In der Zwischenzeit würde ich mich nicht darauf verlassen. Entschuldigen Sie.

Ich werde diese Antwort aktualisieren, sobald sie stabil ist.

+1

Ich stelle mir vor das ist jetzt behoben? Trifecta liegt derzeit bei 1.5.1. –

+2

Wir haben derzeit den Layout-Parser aus dem Mainstream Trifecta entfernt. Sie haben jedoch ein gutes Timing. Ich staue es gerade ab und suche es zu ersetzen. =) –