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.

80 lines
1.4 KiB

2 years ago
  1. {
  2. module Parser where
  3. import Control.Monad.Error
  4. import Lexer.Support
  5. import Syntax
  6. import Lexer (scan)
  7. }
  8. %name parseExpr Expr
  9. %name parseDecl Decl
  10. %tokentype { Token }
  11. %monad { Lexer }
  12. %lexer { lexer } { TkEOF }
  13. %errorhandlertype explist
  14. %error { parseError }
  15. %token
  16. VAR { TkIdent $$ }
  17. 'let' { TkLet }
  18. 'in' { TkIn }
  19. 'where' { TkWhere }
  20. '=' { TkEqual }
  21. '{' { TkOpen }
  22. ';' { TkSemi }
  23. '}' { TkClose }
  24. '\\' { TkBackslash }
  25. '->' { TkArrow }
  26. '(' { TkLParen }
  27. ')' { TkRParen }
  28. OPEN { TkVOpen }
  29. SEMI { TkVSemi }
  30. CLOSE { TkVClose }
  31. %%
  32. Atom :: { Expr }
  33. : VAR { Var $1 }
  34. | '(' Expr ')' { $2 }
  35. Expr :: { Expr }
  36. : '\\' VAR '->' Expr { Lam $2 $4 }
  37. | 'let' DeclBlock 'in' Expr { Let $2 $4 }
  38. | FuncExpr { $1 }
  39. FuncExpr :: { Expr }
  40. : FuncExpr Atom { App $1 $2 }
  41. | Atom { $1 }
  42. DeclBlock :: { [Decl] }
  43. : '{' DeclListSemi '}' { $2 }
  44. | OPEN DeclListSEMI Close { $2 }
  45. DeclListSemi :: { [Decl] }
  46. : Decl ';' DeclListSemi { $1:$3 }
  47. | Decl { [$1] }
  48. | {- empty -} { [] }
  49. DeclListSEMI :: { [Decl] }
  50. : Decl SEMI DeclListSemi { $1:$3 }
  51. | Decl { [$1] }
  52. | {- empty -} { [] }
  53. Close
  54. : CLOSE { () }
  55. | error {% popLayout }
  56. Decl
  57. : VAR '=' Expr { Decl $1 $3 Nothing }
  58. | VAR '=' Expr 'where' DeclBlock { Decl $1 $3 (Just $5) }
  59. {
  60. lexer cont = scan >>= cont
  61. parseError = throwError . show
  62. }