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.

149 lines
4.4 KiB

4 years ago
4 years ago
4 years ago
4 years ago
  1. include import "./lib/parsers.ml"
  2. open import "prelude.ml"
  3. let lex = run_parser
  4. let line_comment () =
  5. let! _ = symbol "--"
  6. let rec go =
  7. let! x = map (const "\n") eof <|> char
  8. if x == "\n" then
  9. pure ()
  10. else
  11. go
  12. go
  13. let whitepiece : forall 'm. monad 'm => parser_t 'm () =
  14. (try (void @@ one_of " \n\v\t\r") <|> try (line_comment ()))
  15. <?> "white space"
  16. let whitespace : forall 'm. monad 'm => parser_t 'm () =
  17. void (many whitepiece)
  18. let lexeme p =
  19. let! _ = whitespace
  20. p
  21. let oparen : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "(")
  22. let cparen : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol ")")
  23. let comma : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol ",")
  24. let semi : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol ";")
  25. let osquare : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "[")
  26. let csquare : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "]")
  27. let obrace : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "{")
  28. let cbrace : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "}")
  29. let back : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "\\")
  30. let arrow : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "->")
  31. let darrow : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "=>")
  32. let equals : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "=")
  33. let pipe : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "|")
  34. let dcolon : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "::")
  35. let small : forall 'm. monad 'm => parser_t 'm string =
  36. try (satisfy (fun c -> "a" <= c && c <= "z") <|> symbol "_") <?> "small letter"
  37. let big : forall 'm. monad 'm => parser_t 'm string =
  38. try (satisfy (fun c -> "A" <= c && c <= "Z")) <?> "big letter"
  39. let iskw = function
  40. | "case"
  41. | "class"
  42. | "data"
  43. | "default"
  44. | "deriving"
  45. | "do"
  46. | "else"
  47. | "if"
  48. | "import"
  49. | "in"
  50. | "infix"
  51. | "infixl"
  52. | "infixr"
  53. | "instance"
  54. | "let"
  55. | "module"
  56. | "newtype"
  57. | "of"
  58. | "foreign"
  59. | "then"
  60. | "type"
  61. | "where"
  62. | "_" -> true
  63. | _ -> false
  64. let isreserved = function
  65. | "=" | "=>" | "->" | "|" -> true
  66. | _ -> false
  67. let varid : forall 'm. monad 'm => parser_t 'm string =
  68. flip (<?>) "variable name" # lexeme @@
  69. let! c = small
  70. let! cs =
  71. many_fold (^) "" (small <|> big <|> try (symbol "'"))
  72. <|> pure ""
  73. let id = c ^ cs
  74. if iskw id then
  75. unexpected id
  76. else
  77. pure id
  78. let conid : forall 'm. monad 'm => parser_t 'm string =
  79. flip (<?>) "constructor name" # lexeme @@
  80. let! c = big
  81. let! cs =
  82. many_fold (^) "" (small <|> big <|> try (symbol "'"))
  83. <|> pure ""
  84. pure (c ^ cs)
  85. let tyvar = varid
  86. let tycon = conid
  87. let tycls = conid
  88. let keyword c = lexeme (symbol c) <?> "``" ^ c ^ "''"
  89. let operator : forall 'm. monad 'm => parser_t 'm string =
  90. flip (<?>) "operator" # lexeme @@
  91. let! c = one_of "!#$%&*+./<=>?@\\^|-~"
  92. let! cs = many_fold (^) "" (one_of ":!#$%&*+./<=>?@\\^|-~")
  93. let op = c ^ cs
  94. if isreserved op then
  95. unexpected op
  96. else
  97. pure op
  98. let digit : forall 'm. monad 'm => parser_t 'm string =
  99. satisfy (fun c -> "0" <= c && c <= "9") <?> "digit"
  100. let hexit : forall 'm. monad 'm => parser_t 'm string =
  101. digit
  102. <|> satisfy (fun c -> "a" <= c && c <= "f")
  103. <|> satisfy (fun c -> "A" <= c && c <= "F")
  104. let integer : forall 'm. monad 'm => parser_t 'm int =
  105. let decimal =
  106. let! c = digit
  107. let! cs = many_fold (^) "" digit
  108. pure (c ^ cs)
  109. let hexadecimal =
  110. let! _ = symbol "0x"
  111. let! c = hexit
  112. let! cs = many_fold (^) "" hexit
  113. pure ("0x" ^ c ^ cs)
  114. let! c = (lexeme (try hexadecimal <|> decimal)) <?> "hex or decimal integer"
  115. match parse_int c with
  116. | None -> error "no parse"
  117. | Some x -> pure x
  118. let string : forall 'm. monad 'm => parser_t 'm string =
  119. flip (<?>) "string literal" # lexeme @@
  120. let parse_escape = function
  121. | "n" -> pure "\n"
  122. | "t" -> pure "\t"
  123. | "\"" -> pure "\""
  124. | a -> unexpected ("escape sequence " ^ a)
  125. let str_ent =
  126. satisfy (fun p -> p <> "\"" && p <> "\\")
  127. <|> ( let! _ = try (symbol "\\")
  128. let! e = char
  129. parse_escape e)
  130. symbol "\"" *> many_fold (^) "" str_ent <* symbol "\""