我正在为大学项目构建java的编译器,在我的项目中,我的解析器大多是StateT (Scope,SymbolTable) String m a
,其中Scope
是我们现在的范围(方法,类等),并且SymbolTable
成立直到现在定义的符号。如何在StateT上使用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
等,这样我可以多次运行解析器,但将结果状态从第一个链接到第二个到第三个等等?
这看起来不对。 'runState'应该让你'((b,s),a)',而不是'[a]',这样你就可以'放'这个状态。 –
@BartekBanachewicz状态是'(b,s)'所以'runState'会返回'(a,(b,s))',我对结果运行函数'f'来得到'[((b,s) ),a)]' – niceman
所以有你的问题。你留下了多个国家。你现在应该选择哪一个? –