Happy bug

Stefan O'Rear stefanor at cox.net
Sat Apr 14 01:47:20 EDT 2007


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.

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.
-------------- next part --------------
-- -*- 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 = []

}


More information about the Glasgow-haskell-users mailing list