I'm building a compiler for java for university project, in my project my parsers are mostly StateT (Scope,SymbolTable) String m a where Scope is the scope we're at now(method,class,etc) and SymbolTable holds the symbols defined till now.
I wanted to use megaparsec's combinators on those parsers, for parens,braces it's not problem, I just use mapStateT but for sepBy and others I developed this function :
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 []
Now f would be for example :
\p -> p `sepBy` semi
Anyway I realized lately that the function above is wrong, the function will run the parser(encapsulated in StateT) feeding it the state we have right now which is s then it will run it again but instead of feeding it the new state resulting from the first run it will feed it s again and again and ... .
How do I use megaparsec's combinators like sepBy,sepEndBy and etc so that I run the parser many times but chaining the resulting state from the first to the second to the third etc ?
I don't know why I thought that I needed a special function to do this,
sepByand others are defined onAlternativeand because everyStateThas anAlternativeinstance functions likesepBy,many, etc can be called directly.My problem probably was because I had to use
symbol,char,etc which I thought areParsecT ...but then I realized those functions are defined in terms ofMonadParsectypeclass whichStateTagain has instance for so I didn't even needliftormapStateT.So all I did is to change functions signatures to work with
MonadParsecand my problem was solved.