Je construis un compilateur Java pour le projet universitaire, dans mon projet mes parseurs sont la plupart du temps StateT (Scope,SymbolTable) String m a
où Scope
est la portée que nous y sommes maintenant (méthode, classe, etc.) et SymbolTable
détient les symboles définis jusqu'à maintenant.comment utiliser les combinateurs de mégaparsec sur StateT
Je voulais utiliser les combinateurs de mégaparsec sur les parseurs, pour parens
, braces
ce n'est pas problème, je viens d'utiliser mapStateT
mais pour sepBy
et d'autres, j'ai développé cette fonction:
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 []
maintenant f
serait par exemple:
\p -> p `sepBy` semi
Quoi qu'il en soit, je réalise que ces derniers temps la fonction ci-dessus est mauvaise, la fonction exécuter l'analyseur (encapsulées dans StateT
) l'alimentant l'état que nous avons en ce moment qui est s
alors il fonctionnera à nouveau mais au lieu de l'alimenter le nouvel état résultant de la première exécution il l'alimentera s
encore et encore et .... Comment est-ce que j'utilise les combinateurs de megaparsec comme sepBy
, sepEndBy
et etc. de sorte que j'exécute l'analyseur plusieurs fois mais en enchaînant l'état résultant de la première à la deuxième à la troisième etc?
Cela semble faux. 'runState' devrait vous obtenir' ((b, s), a) ', pas' [a] ', de sorte que vous puissiez' mettre 'cet état. –
@BartekBanachewicz l'état est '(b, s)' alors 'runState' renverrait' (a, (b, s)) ', j'exécute la fonction' f' sur le résultat pour obtenir '[((b, s), a)] ' – niceman
Donc, il y a votre problème. Vous êtes à gauche avec plusieurs états. Lequel devriez-vous choisir maintenant? –