本文介绍了Parsec中的用户状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Parsec解析一个表达式,并且我想使用Parsec中的用户状态跟踪这些表达式中的变量。不幸的是,我真的不知道该怎么做。

I'm parsing an expression using Parsec and I want to keep track of variables in these expressions using the user state in Parsec. Unfortunately I don't really get how to do it.

给出以下代码:

Given the following code:

import Data.Set as Set
inp = "$x = $y + $z"

data Var = V String

var = do char '$'
      n <- many1 letter
      let v = Var n
       -- I want to modify the set of variables here
      return v

parseAssignment = ... -- parses the above assignment

run = case runIdentity $ runParserT parseAssignment Set.empty "" inp of
                   Left err -> ...
                   Right -> ...

因此, u in ParsecT suma 应该是 Set.Set 。但是,如何将状态更新集成到 var ?

So, the u in ParsecT s u m a would be Set.Set. But how would I integrate the state update into var?

我尝试了类似于修改$ Set.insert v ,但这不起作用,因为 Set.Set 不是状态monad。

I tried something like modify $ Set.insert v, but this doesn't work, since Set.Set is not a state monad.

推荐答案

不幸的是,Yuras建议 updateParserState 不是最优的如果你想修改Parsec的内部状态 );相反,你应该传递一个可以在你的自定义用户状态(即 u - > u 类型)上运行的函数,以 modifyState ,例如在这个例子中:

Unfortunately, Yuras' suggestion of updateParserState is not optimal (you'd use that function if you're looking to modify Parsec's internal state as well); instead you should pass a function that works over your custom user state (i.e. of type u -> u) to modifyState, such as in this example:

expr  = do
  x <- identifier
  modifyState (+1)
  -- ^ in this example, our type u is Int
  return (Id x)

或使用 getState 和 putState 函数的任意组合。对于你的情况,你可以这样做:

or use any combination of the getState and putState functions. For your case, you'd do something like:

modifyState (Set.insert v)

请参阅以获取更多信息。

See this link for more info.

有关更多教程在Parsec中介绍如何使用用户状态,虽然陈旧,应该是相关的。

For a more tutorial-like introduction to working with user state in Parsec, this document, though old, should be relevant.

这篇关于Parsec中的用户状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 18:34