1

I'm building a JavaScript parser in Haskell using Happy and I'm running into an error message that, no matter how hard I try, I can't debug.

I can't really post all the code here as it is thousands of lines long. I'll try to post the relevant bits and if anyone can help me I'd be immensely grateful!

This error message is very long so please bear with me. I've left out most of the HappyAbsSyn part. I can provide the full error message if it will help.

Parser.hs:800:28:
    Couldn't match expected type `Expression'
                with actual type `PrimaryExpr'
    Expected type: Int
                   -> Int
                   -> Token
                   -> HappyState
                        Token
                        (HappyStk
                           (HappyAbsSyn
                              FuncDecl
                              ... etc etc ...
                              PostFix)
                         -> P a1)
                   -> [HappyState
                         Token
                         (HappyStk
                            (HappyAbsSyn
                               FuncDecl
                              ... etc etc ...
                               PostFix)
                          -> P a1)]
                   -> HappyStk
                        (HappyAbsSyn
                           FuncDecl
                              ... etc etc ...
      Actual type: Int
                   -> Int
                   -> Token
                   -> HappyState
                        Token
                        (HappyStk
                           (HappyAbsSyn
                              FuncDecl
                              ... etc etc ...
                              t630)
                         -> P a0)
                   -> [HappyState
                         Token
                         (HappyStk
                            (HappyAbsSyn
                               FuncDecl
                              ... etc etc ...
                               t630)
                          -> P a0)]
                   -> HappyStk
                        (HappyAbsSyn
                           FuncDecl
                              ... etc etc ...
                           t630)
                   -> P a0
    In the first argument of `happyGoto', namely `action_90'
    In the expression: happyGoto action_90

Got that? Ok, so the first thing I did was look at line 800 in Parser.hs (The file generated by Happy).

799: action_60 (7) = happyGoto action_71
800: action_60 (28) = happyGoto action_90
801: action_60 (33) = happyGoto action_15

action_90 is defined as:

action_90 (100) = happyShift action_224
action_90 _ = happyFail

This obviously doesn't make much sense unless we understand what the codes correspond to. I asked Happy to generate an info file when I compiled and this is (I think) the appropriate part:

-----------------------------------------------------------------------------
Grammar
-----------------------------------------------------------------------------
    %start_parse -> program                            (0)
    ... etc etc ...
    statement -> ID ':' statement                      (28)
    ... etc etc ...
    primaryExpr -> THIS                                (100)
    ... etc etc ...

So it looks like it's something to do with an ID statement. I'm really quite confused by this point. Does anyone have any suggestions of where I should go from here? I'm guessing that to work through this, you'd need to see the Abstract Syntax. Here is a bit of it. Again, I'm happy to show more if it helps.

data Expression
    = Assignment    Assignment 
    deriving Show

data Assignment
    = CondExpr        CondExpr
    | Assign          LeftExpr AssignOp Assignment 
    | AssignFuncDecl  FuncDecl
    deriving Show

data FuncDecl
    = FuncDecl      (Maybe String) [String] [Source]
    deriving Show

data Statement
    = EmptyStmt
    | IfStmt        IfStmt
    | IterativeStmt IterativeStmt
    | ExprStmt      Expression
    | Block         [Statement]
    | VarStmt       [VarDecl]
    | TryStmt       TryStmt
    | ContinueStmt  (Maybe String)
    | BreakStmt     (Maybe String)
    | ReturnStmt    (Maybe Expression)
    | WithStmt      Expression Statement
    | LabelledStmt  String Statement
    | Switch        Switch
    | ThrowExpr     Expression
    deriving Show

data PrimaryExpr
    = ExpLitInt     Integer
    | ExpLitStr     String
    | ExpId         String
    | ExpBrackExp   PrimaryExpr
    | ExpThis
    | ExpRegex      String
    | ExpArray      ArrayLit
    | ExpObject     [(Property, Assignment)]
    deriving Show

I'm sorry this is so long. I'm at my wits end here. Any help or pointers would be amazing.

Nick Brunt
  • 9,533
  • 10
  • 54
  • 83
  • The entire happy file being compiled is usually needed (in my experience, but I'm only marginally comfortable in Happy). Also, be sure you're running the latest version of Happy - I've been bitten by bugs before. – Thomas M. DuBuisson Feb 09 '12 at 20:46
  • 5
    Have you tried [adding type signatures](http://www.haskell.org/happy/doc/html/sec-type-signatures.html) to your grammar? It sometimes makes type errors like this one easier to track down. You can also try replacing suspect semantic actions with `undefined`. If that makes it compile, you've likely found the culprit. – hammar Feb 09 '12 at 20:51
  • 2
    You can try slim your example down to a minimal one that still fails. You already suspect it's something with the ID tags so try commenting out lines that do not have anything to do with that. – danr Feb 09 '12 at 21:19
  • Are you missing a constructor and are using a PrimExpression for an Expression in one of your Happy actions? Happy grammars are not type checked, the parsers they generate are - this means type errors can be obscure and take some finding. Do follow **hammar**'s advice and add type signatures to your grammar. – stephen tetley Feb 10 '12 at 08:21
  • This was all brilliant advice. I finally managed to track down the bug by giving everything type signatures like hammar suggested. If you'd like to post that as an answer hammar, I'd be happy to accept it. The error message given to me after I'd added types was much clearer. – Nick Brunt Feb 14 '12 at 02:12

0 Answers0