tempus-0.1.0: Tempus/Parser.y
{
{-# OPTIONS_GHC -w #-}
module Tempus.Parser (
parseProgram,
parseDecl,
parseType,
parseExpr
) where
import Prelude hiding (lex)
import Tempus.Loc
import Tempus.Lexer
import Tempus.Syntax
}
%name pparseProgram prog
%name pparseDecl decl
%name pparseType type
%name pparseExpr expr
%tokentype { Loc Token }
%monad { Parser }
%lexer { lex } { Loc _ EOF }
%error { parseError }
%token
var { Loc _ (Variable _) }
natlit { Loc _ (NatLit _) }
'=' { Loc $$ Equals }
'->' { Loc $$ ArrowRight }
'+' { Loc $$ Plus }
'*' { Loc $$ Times }
'(' { Loc $$ ParenOpen }
')' { Loc $$ ParenClose }
'0' { Loc $$ Zero }
'1' { Loc $$ One }
mu { Loc $$ Mu }
nu { Loc $$ Nu }
'.' { Loc $$ Dot }
',' { Loc $$ Comma }
lam { Loc $$ Lambda }
'[' { Loc $$ SquareOpen }
']' { Loc $$ SquareClose }
langle { Loc $$ AngleOpen }
rangle { Loc $$ AngleClose }
'<*>' { Loc $$ CircledAsterisk }
'<.>' { Loc $$ CircledDot }
'?' { Loc $$ QuestionMark }
'behavior' { Loc $$ KWBehavior }
'case' { Loc $$ KWCase }
'const' { Loc $$ KWConst }
'event' { Loc $$ KWEvent }
'expand' { Loc $$ KWExpand }
'first' { Loc $$ KWFirst }
'fold' { Loc $$ KWFold }
'left' { Loc $$ KWLeft }
'positive' { Loc $$ KWPositive }
'never' { Loc $$ KWNever }
'pack' { Loc $$ KWPack }
'race' { Loc $$ KWRace }
'reflect' { Loc $$ KWReflect }
'right' { Loc $$ KWRight }
'second' { Loc $$ KWSecond }
'ultraswitch' { Loc $$ KWUltraswitch }
'type' { Loc $$ KWType }
'ultrajump' { Loc $$ KWUltrajump }
'unfold' { Loc $$ KWUnfold }
'unpack' { Loc $$ KWUnpack }
'value' { Loc $$ KWValue }
%%
prog :: { Program }
prog : decls { reverse $1 }
decls :: { [Decl] }
decls : { [] }
| decls decl { $2 : $1 }
decl :: { Decl }
decl : typedecl { $1 }
| valdecl { $1 }
typedecl :: { Decl }
typedecl : 'type' var formalargs '=' type { DeclType $1 (var $2) (reverse $3) $5 }
formalargs :: { [Var] }
formalargs : { [] }
| formalargs var { var $2 : $1 }
valdecl :: { Decl }
valdecl : 'value' var '=' expr { DeclVal $1 (var $2) $4 }
type :: { Type }
type : type0 { $1 }
type0 :: { Type }
type0 : mutype { TyMu $1 }
| nutype { TyNu $1 }
| type1 { $1 }
type1 :: { Type }
type1 : type2 '->' type1 { TyFun $1 $3 }
| type2 { $1 }
type2 :: { Type }
type2 : type3 '+' type2 { TyPlus $1 $3 }
| type3 { $1 }
type3 :: { Type }
type3 : type4 '*' type3 { TyPair $1 $3 }
| type4 { $1 }
type4 :: { Type }
type4 : var typeargs { TyApp (var $1) $2 }
| 'behavior' type5 { TyBehav $2 }
| 'event' type5 { TyEvent $2 }
| type5 { $1 }
type5 :: { Type }
type5 : var { TyApp (var $1) [] }
| 'positive' { TyNat }
| '(' type0 ')' { $2 }
| '0' { TyZero }
| '1' { TyUnit }
typeargs :: { [Type] }
typeargs : type5 { [$1] }
| typeargs type5 { $2 : $1 }
mutype :: { MuType }
mutype : mu var '.' type0 { MuType (var $2) $4 }
nutype :: { NuType }
nutype : nu var '.' type0 { NuType (var $2) $4 }
expr :: { Expr }
expr : expr0 { $1 }
expr0 :: { Expr }
expr0 : expr1 ',' expr0 { ExPair $1 $3 }
| expr1 { $1 }
expr1 :: { Expr }
expr1 : lam var '.' expr1 { ExLam (var $2) $4 }
| expr2 { $1 }
expr2 :: { Expr }
expr2 : expr2 '<*>' expr3 { ExLiftAppB $1 $3 }
| expr2 '<.>' expr3 { ExLiftAppE $1 $3 }
| expr3 { $1 }
expr3 :: { Expr }
expr3 : expr3 expr4 { ExApp $1 $2 }
| 'const' expr4 { ExConst $2 }
| 'behavior' expr4 { ExBehav $2 }
| 'event' expr4 expr4 { ExEvent $2 $3 }
| foldvals '[' type ']' expr4 { $1 $3 $5 }
| expr4 { $1 }
expr4 :: { Expr }
expr4 : var { ExVar $ var $1 }
| '1' { ExNatLit 1 }
| natlit { ExNatLit $ nat $1 }
| '(' expr0 ')' { $2 }
| '?' { ExNull }
| langle rangle { ExUnit }
| '(' ')' { ExUnit }
| packvals '[' type ']' { $1 $3 }
| baseval { $1 }
foldvals :: { Type -> Expr -> Expr }
foldvals : 'fold' { ExFold }
| 'unfold' { ExUnfold }
packvals :: { Type -> Expr }
packvals : 'pack' { ExPack }
| 'unpack' { ExUnpack }
baseval :: { Expr }
baseval : 'left' { ExLeft }
| 'right' { ExRight }
| 'case' { ExCase }
| 'first' { ExFst }
| 'second' { ExSnd }
| 'expand' { ExExpand }
| 'never' { ExNever }
| 'race' { ExRace }
| 'reflect' { ExReflect }
| 'ultraswitch' { ExUSwitch }
| 'ultrajump' { ExUJump }
{
-- | Parses a complete Tempus program.
parseProgram :: String -> ParseResult Program
parseProgram = initParser pparseProgram
-- | Parses a single Tempus type or value declaration.
parseDecl :: String -> ParseResult Decl
parseDecl = initParser pparseDecl
-- | Parses a Tempus type expression.
parseType :: String -> ParseResult Type
parseType = initParser pparseType
-- | Parses a Tempus expression.
parseExpr :: String -> ParseResult Expr
parseExpr = initParser pparseExpr
var :: Loc Token -> Var
var (Loc _ (Variable v)) = Var v
var _ = error "internal parser error: unexpected token in var"
nat :: Loc Token -> Integer
nat (Loc _ (NatLit i)) = i
nat _ = error "internal parser error: unexpected token in nat"
parseError :: Loc Token -> Parser a
parseError (Loc loc tok) = fail $ "error parsing token `" ++ showToken tok ++ "' at " ++ show loc
}