我正在使用Parsec解析表达式,我想使用Parsec中的用户状态跟踪这些表达式中的变量。不幸的是,我真的不知道怎么做。
给出以下代码:
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
中的ParsecT s u m a
将为Set.Set
。但是,如何将状态更新集成到var
?
我尝试了类似modify $ Set.insert v
的内容,但这不起作用,因为Set.Set
不是状态monad。
答案 0 :(得分:17)
不幸的是,Yuras对updateParserState
的建议并不是最优的(如果你想要修改Parsec的内部状态,那么你可以使用该函数);相反,您应该将一个适用于您的自定义用户状态(即u -> u
类型)的函数传递给modifyState
,例如在此示例中:
expr = do
x <- identifier
modifyState (+1)
-- ^ in this example, our type u is Int
return (Id x)
或使用getState
和putState
函数的任意组合。对于您的情况,您可以执行以下操作:
modifyState (Set.insert v)
有关详细信息,请参阅this link。
有关在Parsec中使用用户状态的更类似教程的介绍,this document虽然陈旧,但应该是相关的。
答案 1 :(得分:1)
您可以使用updateParserState