Skip to content

Commit

Permalink
Introduce catchTok and modify several definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
Karim Taha committed Jun 28, 2024
1 parent faae80f commit 0ace6dd
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 139 deletions.
49 changes: 38 additions & 11 deletions packages/backend-lalr/data/HappyTemplate.hs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ happyShift new_state ERROR_TOK tk st sts stk@(x `HappyStk` _) =
let i = GET_ERROR_TOKEN(x) in
-- trace "shifting the error token" $
happyDoAction i tk new_state (HappyCons st sts) stk
-- TODO: When `i` would enter error recovery again, we should instead
-- discard input until the lookahead is acceptable. Perhaps this is
-- simplest to implement in CodeGen for productions using `error`;
-- there we know the context and can implement local shift+discard actions.
-- still need to remember parser-defined error site, though.

happyShift new_state i tk st sts stk =
happyNewToken new_state (HappyCons st sts) (MK_TOKEN(tk) `HappyStk` stk)
Expand All @@ -156,8 +161,14 @@ happyShift new_state i tk st sts stk =

happySpecReduce_0 i fn ERROR_TOK tk st sts stk
= happyFail [] ERROR_TOK tk st sts stk
-- SG: I'm very doubtful that passing [] ("no token expected here")
-- as the first arg to happyFail here and in the following calls is
-- correct. I'm not going to touch it for a lack of understanding
-- and concerns of of backward compatibility, but
-- `happyExpListPerState (IBOX(st) :: Prelude.Int)`
-- seems like a good candidate.
happySpecReduce_0 nt fn j tk st sts stk
= happyGoto nt j tk st (HappyCons st sts) (fn `HappyStk` stk)
= happySeq fn (happyGoto nt j tk st (HappyCons st sts) (fn `HappyStk` stk))

happySpecReduce_1 i fn ERROR_TOK tk st sts stk
= happyFail [] ERROR_TOK tk st sts stk
Expand Down Expand Up @@ -226,27 +237,43 @@ happyGoto nt j tk st =
where new_state = happyIndexGotoTable nt st

-----------------------------------------------------------------------------
-- Error recovery (ERROR_TOK is the error token)

-- parse error if we are in recovery and we fail again
-- Error recovery
--
-- When there is no applicable action for the current lookahead token `tk`,
-- happy enters error recovery mode. It works in 2 phases:
--
-- 1. Fixup: Try to see if there is an action for the error token (`errorTok`,
-- which is ERROR_TOK). If there is, do *not* emit an error and pretend
-- instead that an `errorTok` was inserted.
-- When there is no `errorTok` action, call `happyErro` and enter error
-- resumption mode.
-- 2. Error resumption mode: After `happyError` was called TODO: happyError is fatal.
-- Perhaps we should introduce a new `happyAddError`?
-- Current plan: New %resumptive declaration for specifying the two funs,
-- mutually exclusive with %error.
--
-- This is what usually is associated with `error`
-- in `bison` or `menhir`. Since `error` is used for the Fixup mechanism (1)
-- above, we call the corresponding token `catch`.
-- In particular, `catch` will never *omit* calls to `happyFail`.

-- parse error if we are in recovery and reached the end of the state stack
happyFail explist ERROR_TOK tk old_st _ stk@(x `HappyStk` _) =
let i = GET_ERROR_TOKEN(x) in
-- trace "failing" $
happyError_ explist i tk

{- We don't need state discarding for our restricted implementation of
"error". In fact, it can cause some bogus parses, so I've disabled it
for now --SDM
happyError_ explist i tk noResumption_
{-
-- discard a state
happyFail ERROR_TOK tk old_st (HappyCons action sts)
happyFail explist ERROR_TOK tk old_st (HappyCons action sts)
(saved_tok `HappyStk` _ `HappyStk` stk) =
-- trace ("discarding state, depth " ++ show (length stk)) $
happyDoAction ERROR_TOK tk action sts (saved_tok`HappyStk`stk)
-}

-- Enter error recovery: generate an error token,
-- save the old token and carry on.
-- When a `happyShift` accepts, we will pop off the error
-- token to resume parsing with the current lookahead `i`.
happyFail explist i tk action sts stk =
-- trace "entering error recovery" $
happyDoAction ERROR_TOK tk action sts (MK_ERROR_TOKEN(i) `HappyStk` stk)
Expand Down
Loading

0 comments on commit 0ace6dd

Please sign in to comment.