Happy bug

Simon Marlow simonmarhaskell at gmail.com
Mon Apr 16 04:44:03 EDT 2007


Stefan O'Rear wrote:
> stefan at stefans:~/cadt/src$ happy Parser.y
> happy: parE
> stefan at stefans:~/cadt/src$
> 
> A little code examination seems to show that this error cannot occur
> for correct grammars.  But still - it's not helpful.  I would prefer
> to see the actual first error rather than none of the errors.

Yes, this is on my list to fix sometime.  Looking at the code, I can't believe I 
wrote something that fragile, but fixing it properly isn't a quick job.

Thanks for letting me know about the email rejection.

Cheers,
	Simon

> 
> Parser.y is attached.
> 
> 
> I tried to send this to the bug report address, but SimonM's email
> system rejected it as spam, even with a 25-bit hashcash stamp!
> 
> So now all of g-h-u is annoyed.
> 
> 
> ------------------------------------------------------------------------
> 
> -- -*- Haskell -*-
> {
> module Parser where
> }
> 
> %tokentype { Token }
> %error { parse_error }
> %token ID     { T_Id $$ }
>        '\n'   { T_NL }
>        '{'    { T_OB }
>        '}'    { T_CB }
>        '('    { T_OP }
>        ')'    { T_CP }
>        '*'    { T_St }
>        ';'    { T_Se }
>        '|'    { T_Pi }
>        "::="  { T_Sum }
>        "=="   { T_Prod }
>        DERIVE { T_Deriv }
> 
> %%
> 
> spec   :: { State -> State }
> spec    : {- empty -}         { id }
>         | spec line '\n'      { $1 >>> $2 }
> 
> line   :: { State -> State }
> line    : {- empty -}         { id }
>         | DERIVE derivat      { second $2 }
>         | lhs derivat
>           { \(txt, st) -> (txt `cat_st` derive ($2 st) $1, st) }
> 
> lhs    :: { Type }
> lhs     : ID "==" fields      { Prod_T (Product $1 ($3 [])) }
>         | ID "::=" cases      { Sum_T (Sum $1 ($3 [])) }
> 
> cases  :: { [Product] -> [Product] } -- difference list
> cases   : ID fields           { (: Product $1 ($2 [])]) }
>         | cases '|' ID fields { $1 . (: Product $3 ($4 [])) }
> 
> fields :: { [Field] -> [Field] }
> fields  : {- empty -}         { id }
>         | fields field        { $1 . $2 }
> 
> field  :: { Field }
> field   : spquals declars ';' { $2 $1 }
> 
> -- this comes out reversed which is good - c types are written backward
> spquals:: { R_Type }
> spquals : ID                  { R_Tag $1 R_Nil }
>         | spquals ID          { R_Tag $2 $1 }
> 
> declars:: { R_Type -> ([Field] -> [Field]) }
> declars : declar              { (:) . $1 }
>         | declars ',' declar  { \ty -> $1 ty . ($2 ty :) }
> 
> declar :: { R_Type -> Field }
> declar  : '*' declar          { $2 . R_Star }
>         | ID declar           { $2 . R_Tag $1 }
>         | ddeclar             { $1 }
> 
> ddeclar:: { R_Type -> Field }
> ddeclar : ID                  { Field $1 }
>         | '(' declar ')'      { $2 }
> 
> 
> 
> {
> data Token = T_Id String | T_NL | T_OB | T_CB | T_OP | T_CP | T_St
>            | T_Se | T_Pi | T_Sum | T_Prod | T_Deriv
> 
> parseError :: [b] -> a
> parseError _ = error "Parse error"
> 
> lexer [] = []
> lexer ('(':xs) = T_OP : lexer xs
> lexer (')':xs) = T_CP : lexer xs
> lexer ('{':xs) = T_OB : lexer xs
> lexer ('}':xs) = T_CB : lexer xs
> lexer ('*':xs) = T_St : lexer xs
> lexer (';':xs) = T_Se : lexer xs
> lexer ('|':xs) = T_Pi : lexer xs
> lexer (x:xs) | x `elem` " \t\v\r" = lexer xs
> lexer ('\n':x:xs) | isSpace x = lexer (x:xs)
>                   | otherwise = T_NL : lexer (x:xs)
> lexer (x:xs) | isID x = lexID (x:xs)
> 
> lexID (x:xs) | isID x = T_Id (x:name) : rest
>              where (name, rest) = case lexID xs of
>                                         T_Id nam : res -> (nam, res)
>                                         res            -> ("", res)
> lexID cs = lexer cs
> 
> isID x = isAlphaNum x || x == '_'
> 
> -- | The type of supported derivations.
> data Derivation = forall s. Derivation
>     { der_gentext :: Type -> s -> Either String Sect_bag
>     , der_parse   :: Parser Char (s -> s)
>     , der_initial :: s
>     }
> 
> -- |
> -- Types for the sectioned-text output format.
> data Section = Decl_Sect | Defn_Sect deriving(Eq,Enum,Bounded)
> 
> data Sect_bag = ST (Section -> [Char] -> [Char])
> 
> nil_st :: Sect_bag
> nil_st = ST $ \_ -> id
> 
> cat_st :: Sect_bag -> Sect_bag -> Sect_bag
> cat_st (ST f1) (ST f2) = ST $ \s -> f1 s . f2 s
> 
> emit :: Section -> [Char] -> Sect_bag
> emit sec txt = ST $ \sec' -> if sec == sec' then (txt++) else id
> 
> -- |
> -- The central data type used by CADT.  This type represents one CADT
> -- type.  The CADT parser generates a set of these from the input.
> -- The CADT derivers use this to generate code.
> module Type where
> 
> -- | Represents one data type.
> data Type = Sum_T Sum
>           | Prod_T Product
> 
> -- | A sum type; that is, a type consisting of multiple mutually
> -- exclusive cases, each of which is a product, like a discriminated
> -- union.
> data Sum = Sum { s_name  :: String    -- ^ The name of the sum type as
>                                       -- a whole
>                , s_cases :: [Product] -- ^ The set of cases (in source
>                                       -- order)
>                }
> 
> -- | A product type - a set of fields all of which exist.  A C struct.
> data Product = Product { p_name   :: String
>                        , p_fields :: [Field]
>                        }
> 
> -- | A field within a product type.
> data Field = Field { f_name :: String
>                    , f_type :: R_Type
>                    }
> 
> -- | A referencing type, as used in 'Field' definitions to specify the
> -- field type.  While a 'Type' specifies how to build a new type, a
> -- 'R_Type' gives the method for referencing an /existing/ type; in
> -- terms of C 'R_Type' corresponds to specifier, qualifier, and
> -- declarator syntax.
> --
> -- We currently do very little semantic analysis; a R_Type is
> -- represented as a list of words and stars.
> data R_Type = R_Star RType
>             | R_Tag String RType
>             | R_Nil
> 
> 
> all_derivations :: [Derivation]
> all_derivations = []
> 
> }
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users at haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



More information about the Glasgow-haskell-users mailing list