Closed greghendershott closed 10 years ago
So the problem is that the parameter is no longer in scope when you go to force the suspended computation?
Let me think about the best solution. Maybe struct properties would be better than a separate field? Let me know if you have other ideas as well.
So the problem is that the parameter is no longer in scope when you go to force the suspended computation?
Yes, as best I understand.
For example if I stick the following at the top of parsack.rkt
(define lazy values)
(define force values)
Then the parameters have the expected values. (But of course just a quick hack experiment. The parser is much slower as a result.)
Maybe struct properties would be better than a separate field?
Could be, that hadn't occurred to me.
Let me know if you have other ideas as well.
Will do. Thanks!
I did a bit of homework and it looks like Parsec provides "user state" combinators:
http://hackage.haskell.org/package/parsec-2.1.0.1/docs/src/Text-ParserCombinators-Parsec-Prim.html
-----------------------------------------------------------
-- User state combinators
-----------------------------------------------------------
getState :: GenParser tok st st
getState = do{ state <- getParserState
; return (stateUser state)
}
setState :: st -> GenParser tok st ()
setState st = do{ updateParserState (\(State input pos _) -> State input pos st)
; return ()
}
updateState :: (st -> st) -> GenParser tok st ()
updateState f = do{ updateParserState (\(State input pos user) -> State input pos (f user))
; return ()
}
Basically, a key/value store -- such as (hasheq/c symbol? any/c)
-- would just set and get functions is all I would need.
Just a quick initial sketch, but, perhaps it would be nearly as simple as this (plus tests)?
I could work on this more and submit a PR, unless you'd like to take it on?
Your changes look reasonable. If it works for you, then go ahead and commit.
One thought: Maybe the user field should be optional? So you don't have to deal with it if you don't want. You would still have to propagate it in all the other places though (like you already did).
One thought: Maybe the user field should be optional? So you don't have to deal with it if you don't want.
I'm not sure what you mean, how to do that.
Also, unless a Parsack user has made use of the State struct definition, e.g. in a match
or using the State
ctor, this won't break existing code. But if they have, it will. (In hindsight maybe Parsack shouldn't have done (provide (all-defined-out))
?)
Ok never mind I see what you are saying now. Thanks for the pull request!
PR #30 adds the feature.
I have a need to keep track of context (specifically, whether I'm in quotes and whether they're single or double). I reached for Racket parameters, the normal tool for this job. However those don't work in the face of
lazy
andforce
, AFAICT.As a result, I think what I want to do is extend the
State
that's threaded through the parser. But Parsack isn't designed to support that via (say)struct
inheritance. Maybe it could support it via one extrauser
field added toState
, which it simply respects and copies. If the user needs more than one value, they use a hash or put their ownstruct
in there.Any other ideas? And, if you have any ideas that would not require modifying Parsack, I'm definitely open to those as well.