less prototype, less bad code implementation of CCHM type theory
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

132 lines
3.4 KiB

  1. {
  2. module Presyntax.Parser where
  3. import qualified Data.Text as T
  4. import Data.Text (Text)
  5. import Presyntax.Presyntax
  6. import Presyntax.Tokens
  7. import Presyntax.Lexer
  8. import Prelude hiding (span)
  9. }
  10. %name parseExp Exp
  11. %name parseStmt Statement
  12. %name parseProg Program
  13. %tokentype { Token }
  14. %monad { Alex }
  15. %lexer { lexer } { Token TokEof _ _ }
  16. %errorhandlertype explist
  17. %error { parseError }
  18. %token
  19. var { $$@(Token (TokVar _) _ _) }
  20. '(' { Token TokOParen _ _ }
  21. ')' { Token TokCParen _ _ }
  22. '{' { Token TokOBrace _ _ }
  23. '}' { Token TokCBrace _ _ }
  24. '\\' { Token TokLambda _ _ }
  25. '->' { Token TokArrow _ _ }
  26. ':' { Token TokColon _ _ }
  27. ';' { Token TokSemi _ _ }
  28. '=' { Token TokEqual _ _ }
  29. ',' { Token TokComma _ _ }
  30. '*' { Token TokStar _ _ }
  31. '.1' { Token TokPi1 _ _ }
  32. '.2' { Token TokPi2 _ _ }
  33. %%
  34. Exp :: { Expr }
  35. Exp
  36. : Exp ExpProj { span $1 $2 $ App Ex $1 $2 }
  37. | Exp '{' Exp '}' { span $1 $4 $ App Im $1 $3 }
  38. | '\\' LambdaList '->' Exp { span $1 $4 $ makeLams $2 $4 }
  39. | '(' VarList ':' Exp ')' ProdTail { span $1 $6 $ makePis Ex $2 $4 $6 }
  40. | '{' VarList ':' Exp '}' ProdTail { span $1 $6 $ makePis Im $2 $4 $6 }
  41. | ExpProj '->' Exp { span $1 $3 $ Pi Ex (T.singleton '_') $1 $3 }
  42. | '(' VarList ':' Exp ')' '*' Exp { span $1 $7 $ makeSigmas $2 $4 $7 }
  43. | ExpProj '*' Exp { span $1 $3 $ Sigma (T.singleton '_') $1 $3 }
  44. | ExpProj { $1 }
  45. ProdTail :: { Expr }
  46. : '(' VarList ':' Exp ')' ProdTail { span $1 $6 $ makePis Ex $2 $4 $6 }
  47. | '{' VarList ':' Exp '}' ProdTail { span $1 $6 $ makePis Im $2 $4 $6 }
  48. | '->' Exp { span $2 $2 $ $2 }
  49. LambdaList :: { [(Plicity, Text)] }
  50. : var { [(Ex, getVar $1)] }
  51. | var LambdaList { (Ex, getVar $1):$2 }
  52. | '{'var'}' { [(Im, getVar $2)] }
  53. | '{'var'}' LambdaList { (Im, getVar $2):$4 }
  54. LhsList :: { [(Plicity, Text)] }
  55. : { [] }
  56. | LambdaList { $1 }
  57. VarList :: { [Text] }
  58. : var { [getVar $1] }
  59. | var VarList { getVar $1:$2 }
  60. ExpProj :: { Expr }
  61. : ExpProj '.1' { span $1 $2 $ Proj1 $1 }
  62. | ExpProj '.2' { span $1 $2 $ Proj2 $1 }
  63. | Atom { $1 }
  64. Atom :: { Expr }
  65. : var { span $1 $1 $ Var (getVar $1) }
  66. | '(' Tuple ')' { span $1 $3 $ $2 }
  67. Tuple :: { Expr }
  68. : Exp { $1 }
  69. | Exp ',' Tuple { span $1 $3 $ Pair $1 $3 }
  70. Statement :: { Statement }
  71. : var ':' Exp { Decl (getVar $1) $3 }
  72. | var LhsList '=' Exp { Defn (getVar $1) (makeLams $2 $4) }
  73. Program :: { [Statement] }
  74. : Statement { [$1] }
  75. | Statement ';' Program { $1:$3 }
  76. {
  77. lexer cont = alexMonadScan >>= cont
  78. parseError x = alexError (show x)
  79. makeLams xs b = foldr (uncurry Lam) b xs
  80. makePis p xs t b = foldr (flip (Pi p) t) b xs
  81. makeSigmas xs t b = foldr (flip Sigma t) b xs
  82. class HasPosn a where
  83. startPosn :: a -> Posn
  84. endPosn :: a -> Posn
  85. instance HasPosn Token where
  86. startPosn (Token _ l c) = Posn l c
  87. endPosn (Token t l c) = Posn l (c + tokSize t)
  88. instance HasPosn Expr where
  89. startPosn (Span _ s _) = s
  90. startPosn _ = error "no start posn in parsed expression?"
  91. endPosn (Span _ _ e) = e
  92. endPosn _ = error "no end posn in parsed expression?"
  93. span s e ex = Span ex (startPosn s) (endPosn e)
  94. getVar (Token (TokVar s) _ _) = s
  95. getVar _ = error "getVar non-var"
  96. }