Ich baue einen Compiler für Java für Universitätsprojekt, in meinem Projekt sind meine Parser meistens StateT (Scope,SymbolTable) String m a
wo Scope
der Bereich ist, in dem wir jetzt sind (Methode, Klasse, etc) und SymbolTable
hält die bis jetzt definierten Symbole.wie megaparsecs Kombinatoren auf StateT verwenden
Ich wollte megaparsec die combinators auf diesen Parser verwenden, für parens
, braces
es ist nicht Problem, ich mapStateT
gerade, aber ich diese Funktion entwickelt für sepBy
und andere verwenden:
mapsequence :: (Monoid s,Monad m) => (m (a,(b,s)) -> m [(a,(b,s))]) -> StateT (b,s) m a -> StateT (b,s) m [a]
mapsequence f stm = do
s <- get
ases <- lift $ f $ runStateT stm s
case ases of
(_:_) -> do
put ((fst . snd . last) ases,(mconcat . map (snd . snd)) ases)
return $ map fst ases
[] -> return []
Jetzt f
zum Beispiel wäre:
\p -> p `sepBy` semi
auf jeden Fall wurde mir klar, in letzter Zeit, dass die Funktion über falsch ist, wird die Funktion des Parsers (eingekapselt inlaufen) füttere es den Zustand, den wir jetzt haben, der s
ist, dann wird es es wieder laufen lassen, aber anstatt es den neuen Zustand zu geben, der vom ersten Lauf resultiert, wird es ihn s
immer wieder füttern und ....
Wie benutze ich megaparsecs Kombinatoren wie sepBy
, sepEndBy
und etc, so dass ich den Parser viele Male laufen lasse, aber den resultierenden Zustand vom ersten zum zweiten bis zum dritten usw. verkette?
Das sieht falsch aus. 'runState' sollte dir' ((b, s), a) ', nicht' [a] 'bringen, damit du diesen Zustand" putten "kannst. –
@BartekBanachewicz der Zustand ist '(b, s)' so 'runState' würde zurückgeben' (a, (b, s)) ', ich führe die Funktion' f' auf das Ergebnis, um '[((b, s), a)] ' – niceman
Also, da ist dein Problem. Sie haben mehrere Zustände. Welchen solltest du jetzt auswählen? –