Created
January 11, 2013 20:33
-
-
Save anonymous/4513751 to your computer and use it in GitHub Desktop.
A sample Happy parser for a very simple functional language.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
module Parser where | |
import Data.Char | |
import Lambda | |
} | |
%name lambda | |
%tokentype { Token } | |
%error { parseError } | |
%token | |
let { TokenLet } | |
in { TokenIn } | |
var { TokenVar $$ } | |
fix { TokenFix } | |
'=' { TokenEq } | |
'\\' { TokenLambda } | |
'.' { TokenDot } | |
'(' { TokenOB } | |
')' { TokenCB } | |
int { TokenInt $$ } | |
%% | |
Exp : NoAppExp { $1 } | |
| Exp NoAppExp { $1 :$ $2 } | |
NoAppExp : let var '=' Exp in Exp { Let $2 $4 $6 } | |
| '(' Exp ')' { $2 } | |
| int { BuiltIn (Nat $1) } | |
| var { LVar $1 } | |
| '\\' var '.' Exp { Abstract $2 $4 } | |
| fix var '.' Exp { Fix $2 $4 } | |
{ | |
parseError :: [Token] -> a | |
parseError _ = error "Parse error" | |
type Var = String | |
type Exp = LTerm Var | |
{- | |
data Exp | |
= Let Var Exp Exp | |
| App Exp Exp | |
| Abs Var Exp | |
| Fix Var Exp | |
| Var Var | |
| NumLit Integer | |
deriving (Show, Eq, Ord) | |
-} | |
data Token | |
= TokenLet | |
| TokenIn | |
| TokenFix | |
| TokenEq | |
| TokenLambda | |
| TokenDot | |
| TokenOB | |
| TokenCB | |
| TokenInt Integer | |
| TokenVar String | |
deriving (Show, Eq, Ord) | |
lexer :: String -> [Token] | |
lexer [] = [] | |
lexer (c:cs) | |
| isSpace c = lexer cs | |
| isAlpha c = lexVar (c:cs) | |
| isDigit c = lexNum (c:cs) | |
lexer ('=':cs) = TokenEq : lexer cs | |
lexer ('\\':cs) = TokenLambda : lexer cs | |
lexer ('.':cs) = TokenDot : lexer cs | |
lexer ('(':cs) = TokenOB : lexer cs | |
lexer (')':cs) = TokenCB : lexer cs | |
lexNum cs = TokenInt (read num) : lexer rest | |
where (num,rest) = span isDigit cs | |
lexVar cs = | |
case span isAlpha cs of | |
("let",rest) -> TokenLet : lexer rest | |
("in",rest) -> TokenIn : lexer rest | |
("fix",rest) -> TokenFix : lexer rest | |
(var,rest) -> TokenVar var : lexer rest | |
main = getContents >>= print . lambda . lexer | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment