
Hi! I'm trying to use a partial monadic parser with Happy (using %partial %monad and %lexer). The problem is that the parser function always seems to eat up one token beyond the matched sequence regardless of what I do. So I can't, for instance, call the parser multiple times to parse a series of blocks, because after the first block is done, it misses the first token of the second block. I'm sure this has to have come up for someone before, but I've been unable to find any references. JCAB

More info: I managed to do a hack that works around it, but it is
clearly not acceptable. Part of the Haskell code generated by Happy
contains this:
---------------------------------------------------------------------------
-- Accepting the parse
-- If the current token is 0#, it means we've just accepted a partial
-- parse (a %partial parser). We must ignore the saved token on the top of
-- the stack in this case.
happyAccept 0# tk st sts (_ `HappyStk` ans `HappyStk` _) =
happyReturn1 ans
happyAccept j tk st sts (HappyStk ans _) =
(happyTcHack j (happyTcHack st)) (happyReturn1 ans)
That looked suspect. There's a "tk" parameter that is summarily
ignored! So I started mucking with it. I added a new action to "recover" a
token by storing it in the monad's state, so that the lexer function can
provide it again, and used it in there:
---------------------------------------------------------------------------
-- Accepting the parse
-- If the current token is 0#, it means we've just accepted a partial
-- parse (a %partial parser). We must ignore the saved token on the top of
-- the stack in this case.
happyAccept 0# tk st sts (_ `HappyStk` ans `HappyStk` _) =
recoverToken tk >> happyReturn1 ans -- Modification!!!
happyAccept j tk st sts (HappyStk ans _) =
(happyTcHack j (happyTcHack st)) (happyReturn1 ans)
With that modification, everything seems to work correctly (yay!)
It is insufficient, though, because this code is generated by Happy, so
I'd need to change it by hand every time. The fact that this parameter is
there seems to indicate that it might sometimes get used for some purpose,
so maybe there's a "better way"?
JCAB
On Fri, 13 Apr 2007 15:23:14 -0700, Juan Carlos Arevalo Baeza
Hi! I'm trying to use a partial monadic parser with Happy (using %partial %monad and %lexer). The problem is that the parser function always seems to eat up one token beyond the matched sequence regardless of what I do. So I can't, for instance, call the parser multiple times to parse a series of blocks, because after the first block is done, it misses the first token of the second block.
I'm sure this has to have come up for someone before, but I've been unable to find any references.
JCAB _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Juan Carlos Arevalo Baeza wrote:
More info: I managed to do a hack that works around it, but it is clearly not acceptable. Part of the Haskell code generated by Happy contains this:
--------------------------------------------------------------------------- -- Accepting the parse
-- If the current token is 0#, it means we've just accepted a partial -- parse (a %partial parser). We must ignore the saved token on the top of -- the stack in this case. happyAccept 0# tk st sts (_ `HappyStk` ans `HappyStk` _) = happyReturn1 ans happyAccept j tk st sts (HappyStk ans _) = (happyTcHack j (happyTcHack st)) (happyReturn1 ans)
That looked suspect. There's a "tk" parameter that is summarily ignored! So I started mucking with it. ...
You're quite right, Happy does consume an extra token because it always has one token of lookahead. The %partial feature was added mainly so that I could parse the header of a module in GHC without parsing the whole module, so I didn't need to recover and parse the rest of the module in this case. By all means fix Happy in whatever way you think is useful, and send me the patch. Cheers, Simon
participants (2)
-
Juan Carlos Arevalo Baeza
-
Simon Marlow