2011-06-25 9 views
16

私はParsecを使用して式を解析しています。これらの式の変数を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 -> ... 

ので、ParsecT s u m auSet.Set次のようになります。

は、次のコードを考えます。しかし、私はどのようにvarに状態の更新を統合するのですか?

私はmodify $ Set.insert vのようなものを試しましたが、Set.Setは状態のモナドではないため、これは機能しません。

答えて

16

を使用することができます。

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

またはgetStateputState機能を任意に組み合わせて使用​​します。代わりに、あなたは、このような本例のようにmodifyStateに(すなわちタイプu -> uの)カスタムユーザーの状態、上で動作する関数を渡す必要があります。

modifyState (Set.insert v) 

は、詳細はthis linkを参照してください:あなたのケースでは、あなたのような何かをしたいです。

Parsecのユーザ状態を扱うためのチュートリアルのような紹介については、this documentが古いとはいえ、関連性があるはずです。

+0

ありがとう!それはまさに私が必要とするものです。以前はその関数を見ていた可能性があります...私は何とかmodifyStateがControl.Monad.Stateからの変更に関連していると考えました。 – bzn

+0

@bzn:でもそれは関連しています!あなたがParsecをユーザー状態だけを保持する状態のモナドと考えるならば、同じことをします。 'modifyState'がParsecの内部状態を無視するためにのみ違いがあります。 –

1

あなたは(あなたがParsecの内部の状態同様を修正するために探している場合は、その機能を使用すると思います)残念ながら、updateParserStateのYuras'提案は最適ではないupdateParserState

+0

ありがとう、それは動作しますが、Raeez Lorgatが言ったように、modifyStateは必要な機能のようです。 – bzn

関連する問題