Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

normalize whitespace #5

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
189 changes: 94 additions & 95 deletions src/charparse.sig
Original file line number Diff line number Diff line change
Expand Up @@ -3,100 +3,99 @@
signature CHAR_PARSER =
sig

(* type synonym for Parsing.parser working on character streams *)
type 'a charParser = ('a, char) ParserCombinators.parser
type message = char ParserCombinators.message

(* (oneOf cs) succeeds if the current character is in the supplied list of
characters cs. Returns the parsed character. See also satisfy.

vowel = oneOf "aeiou"
*)
val oneOf : char list -> char charParser

(* As the dual of oneOf, (noneOf cs) succeeds if the current character not
in the supplied list of characters cs. Returns the parsed character.

consonant = noneOf "aeiou"
*)
val noneOf : char list -> char charParser

(* (char c) parses a single character c. Returns the parsed character
(i.e. c).

semiColon = char #";"
*)
val char : char -> char charParser

(* (string s) parses a sequence of characters given by s. Returns the
parsed string (i.e. s).

divOrMod = string "div"
|| string "mod"
*)
val string : string -> string charParser

(* This parser succeeds for any character. Returns the parsed character. *)
val anyChar : char charParser

(* Parses an upper case letter (a character between #"A" and #"Z"). Returns
the parsed character.
*)
val upper : char charParser

(* Parses a lower case character (a character between #"a" and #"z").
Returns the parsed character.
*)
val lower : char charParser

(* Parses a letter (an upper case or lower case character). Returns the
parsed character.
*)
val letter : char charParser

(* Parses a letter or digit. Returns the parsed character. *)
val alphaNum : char charParser
(* Parses a digit (a character between '0' and '9'). Returns the parsed
character.
*)
val digit : char charParser

(* Parses a hexadecimal digit (a digit or a letter between 'a' and 'f' or
'A' and 'F'). Returns the parsed character.
*)
val hexDigit : char charParser

(* Parses an octal digit (a character between '0' and '7'). Returns the
parsed character.
*)
val octDigit : char charParser

(* Parses a newline character (#"\n"). Returns a newline character. *)
val newLine : char charParser

(* Parses a tab character (#"\t"). Returns a newline character. *)
val tab : char charParser

(* Parses a white space character (any character in " \v\f\t\r\n"). Returns
the parsed character.
*)
val space : char charParser

(* Skips zero or more white space characters. See also repeati
*)
val spaces : unit charParser

(* The parser (satisfy f) succeeds for any character for which the supplied
function f returns true. Returns the character that is actually parsed.
*)
val satisfy : (char -> bool) -> char charParser

(* Formatter for messages over char streams *)
val messageToString : message -> string

(* Parse function that uses the default formatter for char streams *)
val parseChars : 'a charParser -> (char * Coord.t) Stream.stream ->
(string, 'a) Sum.sum
val parseString : 'a charParser -> string -> (string, 'a) Sum.sum
(* type synonym for Parsing.parser working on character streams *)
type 'a charParser = ('a, char) ParserCombinators.parser
type message = char ParserCombinators.message

(* (oneOf cs) succeeds if the current character is in the supplied list of
characters cs. Returns the parsed character. See also satisfy.

vowel = oneOf "aeiou"
*)
val oneOf : char list -> char charParser

(* As the dual of oneOf, (noneOf cs) succeeds if the current character not
in the supplied list of characters cs. Returns the parsed character.

consonant = noneOf "aeiou"
*)
val noneOf : char list -> char charParser

(* (char c) parses a single character c. Returns the parsed character
(i.e. c).

semiColon = char #";"
*)
val char : char -> char charParser

(* (string s) parses a sequence of characters given by s. Returns the
parsed string (i.e. s).

divOrMod = string "div" || string "mod"
*)
val string : string -> string charParser

(* This parser succeeds for any character. Returns the parsed character. *)
val anyChar : char charParser

(* Parses an upper case letter (a character between #"A" and #"Z"). Returns
the parsed character.
*)
val upper : char charParser

(* Parses a lower case character (a character between #"a" and #"z").
Returns the parsed character.
*)
val lower : char charParser

(* Parses a letter (an upper case or lower case character). Returns the
parsed character.
*)
val letter : char charParser

(* Parses a letter or digit. Returns the parsed character. *)
val alphaNum : char charParser

(* Parses a digit (a character between '0' and '9'). Returns the parsed
character.
*)
val digit : char charParser

(* Parses a hexadecimal digit (a digit or a letter between 'a' and 'f' or
'A' and 'F'). Returns the parsed character.
*)
val hexDigit : char charParser

(* Parses an octal digit (a character between '0' and '7'). Returns the
parsed character.
*)
val octDigit : char charParser

(* Parses a newline character (#"\n"). Returns a newline character. *)
val newLine : char charParser

(* Parses a tab character (#"\t"). Returns a newline character. *)
val tab : char charParser

(* Parses a white space character (any character in " \v\f\t\r\n"). Returns
the parsed character.
*)
val space : char charParser

(* Skips zero or more white space characters. See also repeati
*)
val spaces : unit charParser

(* The parser (satisfy f) succeeds for any character for which the supplied
function f returns true. Returns the character that is actually parsed.
*)
val satisfy : (char -> bool) -> char charParser

(* Formatter for messages over char streams *)
val messageToString : message -> string

(* Parse function that uses the default formatter for char streams *)
val parseChars : 'a charParser -> (char * Coord.t) Stream.stream -> (string, 'a) Sum.sum
val parseString : 'a charParser -> string -> (string, 'a) Sum.sum

end
96 changes: 52 additions & 44 deletions src/charparse.sml
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,57 @@
structure CharParser :> CHAR_PARSER =
struct

open ParserCombinators
infixr 4 << >>
infixr 1 ??

type 'a charParser = ('a, char) parser
type message = char message

fun oneOf xs = try (satisfy (fn x => List.exists (fn y => x = y) xs))
fun noneOf xs = try (satisfy (fn x => List.all (fn y => x <> y) xs))
fun char x = try (satisfy (fn y => x = y)) ?? "'" ^ str x ^ "'"
fun string s =
let fun string_aux xs = case xs of
nil => succeed s
| (x :: xs') => char x >> string_aux xs'
in string_aux (String.explode s) end

val anyChar = any
val upper = try (satisfy Char.isUpper) ?? "upper case letter"
val lower = try (satisfy Char.isLower) ?? "lower case letter"
val letter = try (satisfy Char.isAlpha) ?? "letter"
val alphaNum = try (satisfy Char.isAlphaNum) ?? "alphanumeric character"
val digit = try (satisfy Char.isDigit) ?? "digit"
val hexDigit = try (satisfy Char.isHexDigit) ?? "hexadecimal digit"
val octDigit = try (satisfy (fn x => Char.isDigit x
andalso Char.<= (x, #"7"))) ?? "octal digit"
val newLine = char #"\n" ?? "'\n'"
val tab = char #"\t" ?? "'\t'"
val space = try (satisfy Char.isSpace)
val spaces = repeatSkip space
val satisfy = satisfy

fun messageToString m =
case m of
Unexpected (SOME t) => "unexpected '" ^ str t ^ "'"
| Unexpected NONE => "unexpected end of stream"
| Expected s => s
| Message m => m

fun parseChars p = parse messageToString p
fun parseString p s =
let val s = CoordinatedStream.coordinate (fn x => Stream.hd x = #"\n" handle Stream.Empty => false) (Coord.init "-")
(Stream.fromString s)
in parseChars p s
end
open ParserCombinators
infixr 4 << >>
infixr 1 ??

type 'a charParser = ('a, char) parser
type message = char message

fun oneOf xs = try (satisfy (fn x => List.exists (fn y => x = y) xs))
fun noneOf xs = try (satisfy (fn x => List.all (fn y => x <> y) xs))
fun char x = try (satisfy (fn y => x = y)) ?? "'" ^ str x ^ "'"
fun string s =
let
fun string_aux xs =
case xs of
[] => succeed s
| (x :: xs') => char x >> string_aux xs'
in
string_aux (String.explode s)
end

val anyChar = any
val upper = try (satisfy Char.isUpper) ?? "upper case letter"
val lower = try (satisfy Char.isLower) ?? "lower case letter"
val letter = try (satisfy Char.isAlpha) ?? "letter"
val alphaNum = try (satisfy Char.isAlphaNum) ?? "alphanumeric character"
val digit = try (satisfy Char.isDigit) ?? "digit"
val hexDigit = try (satisfy Char.isHexDigit) ?? "hexadecimal digit"
val octDigit = try (satisfy (fn x => Char.isDigit x andalso Char.<= (x, #"7"))) ?? "octal digit"
val newLine = char #"\n" ?? "'\n'"
val tab = char #"\t" ?? "'\t'"
val space = try (satisfy Char.isSpace)
val spaces = repeatSkip space
val satisfy = satisfy

fun messageToString m =
case m of
Unexpected (SOME t) => "unexpected '" ^ str t ^ "'"
| Unexpected NONE => "unexpected end of stream"
| Expected s => s
| Message m => m

fun parseChars p = parse messageToString p
fun parseString p s =
let
val s =
CoordinatedStream.coordinate
(fn x => Stream.hd x = #"\n" handle Stream.Empty => false)
(Coord.init "-")
(Stream.fromString s)
in
parseChars p s
end

end
Loading