2011-06-25 12 views
16

Estoy analizando una expresión usando Parsec y quiero hacer un seguimiento de las variables en estas expresiones usando el estado del usuario en Parsec. Lamentablemente, realmente no entiendo cómo hacerlo.Estado del usuario en Parsec

Dado el siguiente código:

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 -> ... 

Así, el u en ParsecT s u m a habría Set.Set. ¿Pero cómo integraría la actualización de estado en var?

Intenté algo como modify $ Set.insert v, pero esto no funciona, ya que Set.Set no es una mónada de estado.

Respuesta

16

Por desgracia, la sugerencia de updateParserState Yuras' no es óptima (que tendría que utilizar esta función si usted está buscando para modificar el estado interno de Parsec, así); en su lugar debe pasar una función que funciona sobre su estado de usuario personalizado (es decir, del tipo u -> u) a modifyState, como en este ejemplo:

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

o utilizar cualquier combinación de las getStateputState y funciones. Para su caso, usted haría algo como:

modifyState (Set.insert v) 

Ver this link para obtener más información.

Para una introducción más similar al tutorial para trabajar con el estado del usuario en Parsec, this document, aunque antiguo, debe ser relevante.

+0

Gracias! Eso es exactamente lo que necesito, podría haber mirado esa función antes ... de alguna manera pensé que modifyState estaba relacionado para modificar desde Control.Monad.State. – bzn

+0

@bzn: ¡Está relacionado, sin embargo! Si piensas en Parsec como una mónada de estado que solo tiene el estado de usuario, hacen lo mismo. Se diferencian solo porque 'modifyState' ignora el estado interno de Parsec. –

1

Puede utilizar updateParserState

+0

gracias, eso funciona, pero como dijo Raeez Lorgat, modifyState parece ser la función que necesito. – bzn

Cuestiones relacionadas