Sven Panne <[EMAIL PROTECTED]> writes:
> [ I'm not quite sure if glasgow-haskell-bugs is the right place for
> mailing this, but since Happy is now part of GHC... ]
It's as good a place as any...
> Given the following (heavily boilt down) specification, Happy prints the
> incredibly informative message "Fail: spontaneous" and dies.
>
> --------------------------------------------
> %tokentype { Token }
> %token IDENTIFIER { TokenIdentifier }
> '+' { TokenPlus }
> %%
> Expr :: { Int }
> : Term { 42 }
>
> Term :: { Int }
> : IDENTIFIER { 42 }
> | Expr '+' Term { 42 }
> --------------------------------------------
This is a bug that falls into the "how did it ever work" category.
Patch follows.
*** LALR.lhs 1997/09/09 16:31:45 1.6
--- LALR.lhs 1997/09/23 14:51:25
***************
*** 66,98 ****
> Just c -> c
> where
>
> nts = getNonTerminals g
> first_term = getFirstTerm g
- >
- > (info,_) = foldr (\n (h,c) -> follow h n []) ([],[]) nts
- > info' = map (\(n,rules) -> (n,map (\rule -> (rule,0)) rules)) info
- >
- > follow h n loop
- > | n `elem` loop = (h,[])
- > | otherwise =
- > case lookup n h of
- > Nothing -> let rules = lookupProdsOfName g n
- > (h',c) = follows h rules [] (n:loop)
- > in
- > ((n,c) : h', c)
- > Just c -> (h, c)
- >
- > follows h [] rs loop = (h, rs)
- > follows h (rule:rules) rs' loop =
- > case findRule g rule 0 of
- > (Just nt) | nt >= 0 && nt < first_term ->
- > let (h',c) = follow h nt loop
- > rs'' = filter (`notElem` rs') (rule:c) ++ rs'
- > in
- > follows h' rules rs'' loop
- > _ -> follows h rules (if rule `elem` rs'
- > then rs'
- > else rule:rs') loop
> closure0 :: GrammarInfo -> (Name -> RuleList) -> Set Lr0Item -> Set Lr0Item
> closure0 g closureOfNT set = mkSet (foldr addRules emptySet set)
--- 66,87 ----
> Just c -> c
> where
>
+ > info' = map (\(n,rules) -> (n,map (\rule -> (rule,0)) rules)) info
+ > info = mkClosure (==) (\f -> map (follow f) f)
+ > (map (\nt -> (nt,lookupProdsOfName g nt)) nts)
+
+ > follow f (nt,rules) = (nt, foldr union rules (map (followNT f) rules))
+
+ > followNT f rule =
+ > case findRule g rule 0 of
+ > Just nt | nt >= 0 && nt < first_term ->
+ > case lookup nt f of
+ > Just rs -> rs
+ > Nothing -> error "followNT"
+ > _ -> []
+
> nts = getNonTerminals g
> first_term = getFirstTerm g
> closure0 :: GrammarInfo -> (Name -> RuleList) -> Set Lr0Item -> Set Lr0Item
> closure0 g closureOfNT set = mkSet (foldr addRules emptySet set)
> Another (probably easy-to-fix) glitch: Using comments and multi-line
> code confuses Happy's line numbering in error messages. (Yacc/Bison are
> not better, either, but why should one imitate bad habits?) It's quite
> hard to explain the advantages of frontend generators to students while
> not being able to find a simple typo... :'-(
Ok, could you give an example? I tried to fix most of the
wrong-line-number-in-error-message type problems, but I may have
missed some.
Cheers,
Simon
--
Simon Marlow [EMAIL PROTECTED]
University of Glasgow http://www.dcs.gla.ac.uk/~simonm/
finger for PGP public key