Daniel Gattesco
Daniel Gattesco

Reputation: 23

Parsing "case of" statement with Happy

Another day, another question: I'm trying to create a parser in Happy which can recognize Haskell integers, identificators, function applications, let in and case of statements. I don't really know how to parse multiple cases in the case of statement. I tried to follow the user's guide but honestly couldn't figure it out anyway.

Another similar problem happens for the function application parsing. Apparently if i want to parse something like

f x y

I get

Application (Id "f") (Application (Id "x") (Id "y"))

and not what i expect, which is

Application (Application (Id "f") (Id "x")) (Id "y)

Can someone help me? Thanks.

--Happy parser

{
module Main where
import Lexer
}

%name parse
%tokentype {Token}
%error {parseError}

%token
    let             { TokenLet }
    in              { TokenIn }
    case            { TokenCase }
    of              { TokenOf }
    '+'             { TokenPlus }
    '-'             { TokenMinus }
    '*'             { TokenTimes }
    '/'             { TokenDiv }
    '='             { TokenEqual }
    '('             { TokenOpenRoundPar }
    ')'             { TokenCloseRoundPar }
    '['             { TokenOpenSquaredPar }
    ']'             { TokenCloseSquaredPar }
    '{'             { TokenOpenCurlyBrace }
    '}'             { TokenCloseCurlyBrace }
    int             { TokenInt $$ }
    var             { TokenId $$ }
    application     { TokenApplication $$ }

%left '+' '-'
%left '*' '/'
%nonassoc application

%%
Exp : let var '=' Exp in Exp        { Let $2 $4 $6 }
  **| case var of Exp               { Case $2 $4 } <-- Don't know how to parse multiple cases!**
    | Exp '+' Exp                   { Plus $1 $3 }
    | Exp '-' Exp                   { Minus $1 $3 }
    | Exp '*' Exp                   { Times $1 $3 }
    | Exp '/' Exp                   { Div $1 $3 }
    | Exp '=' Exp                   { Equal $1 $3} 
    | '(' Exp ')'                   { RoundBrack $2 }
    | '[' Exp ']'                   { SquaredBrack $2 }
    | '{' Exp '}'                   { CurlyBrack $2 }
    | int                           { Int $1 }
    | var                           { Id $1 }
    | Exp Exp %prec application     { Application $1 $2}

{
parseError :: [Token] -> a
parseError _ = error "ParseError"

data Exp = Let String Exp Exp
        | Case String Exp
        | Plus Exp Exp
        | Minus Exp Exp
        | Times Exp Exp
        | Div Exp Exp
        | Equal Exp Exp
        | RoundBrack Exp
        | SquaredBrack Exp
        | CurlyBrack Exp
        | Int Int
        | Id String
        | Application Exp Exp
        deriving (Show)

main = do
        s <- getLine
        print(parse (lexer s))
}

Upvotes: 0

Views: 149

Answers (0)

Related Questions