我正在为大学项目构建一个 java 编译器,在我的项目中,我的解析器主要位于我们现在StateT (Scope,SymbolTable) String m a
所处的范围(方法、类等)并保存到目前为止定义的符号。 Scope
SymbolTable
我想在这些解析器上使用 megaparsec 的组合器,因为parens
,braces
这不是问题,我只是使用mapStateT
,但是对于sepBy
其他人,我开发了这个函数:
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 []
现在f
例如:
\p -> p `sepBy` semi
无论如何,我最近意识到上面的函数是错误的,该函数将运行解析器(封装在 中StateT
)向它提供我们现在拥有的状态,s
然后它将再次运行它,而不是向它提供第一次运行产生的新状态它会s
一次又一次地喂它,然后......
如何使用 megaparsec 的组合器,例如sepBy
,sepEndBy
等等,以便我多次运行解析器,但将结果状态从第一个到第二个到第三个等链接起来?