parsing¶
In [ ]:
open sm'_operators
In [ ]:
//// test
open testing
fparsec¶
In [ ]:
//// test
#r @"../../../../../../../.nuget/packages/fparsec/2.0.0-beta2/lib/netstandard2.1/FParsec.dll"
#r @"../../../../../../../.nuget/packages/fparsec/2.0.0-beta2/lib/netstandard2.1/FParsecCS.dll"
///! _
()
In [ ]:
//// test
nominal position_ = $'FParsec.Position'
nominal parser_error_ = $'FParsec.Error.ParserError'
nominal reply_ t = $'FParsec.Reply<`t>'
nominal char_stream_ t = $'FParsec.CharStream<`t>'
// nominal parser t u = char_stream u -> reply t
nominal parser_ t u = $'FParsec.Primitives.Parser<`t, `u>'
inl p_char_ forall t. (x : char) : parser_ char t =
x |> $'FParsec.CharParsers.pchar'
inl p_string_ forall t. (x : string) : parser_ string t =
x |> $'FParsec.CharParsers.pstring'
inl (>>.$) forall t u v. (a : parser_ t v) (b : parser_ u v) : parser_ u v =
b |> $'FParsec.Primitives.(>>.)' a
inl (.>>$) forall t u v. (a : parser_ t v) (b : parser_ u v) : parser_ t v =
b |> $'FParsec.Primitives.(.>>)' a
inl (.>>.$) forall t u v. (a : parser_ t v) (b : parser_ u v) : parser_ (pair t u) v =
b |> $'FParsec.Primitives.(.>>.)' a
inl (>>%$) forall t u v. (a : parser_ t v) (b : u) : parser_ u v =
b |> $'FParsec.Primitives.(>>%)' a
inl (>>=$) forall t u v. (a : parser_ t v) (b : t -> parser_ u v) : parser_ u v =
b |> $'FParsec.Primitives.(>>=)' a
inl (|>>$) forall t u v. (a : parser_ t v) (b : t -> u) : parser_ u v =
inl b = fun x => x |> b
b |> $'FParsec.Primitives.(|>>)' a
inl any_char_ () : parser_ char _ =
$'FParsec.CharParsers.anyChar'
inl any_string_ () : parser_ string _ =
$'FParsec.CharParsers.anyString'
inl any_string__ (n : i32) : parser_ string _ =
n |> $'FParsec.CharParsers.anyString'
inl eof_ () : parser_ () _ =
$'FParsec.CharParsers.eof'
inl spaces_ () : parser_ () () =
$'FParsec.CharParsers.spaces'
inl spaces1_ () : parser_ () () =
$'FParsec.CharParsers.spaces1'
inl (<|>$) forall t u. (a : parser_ t u) (b : parser_ t u) : parser_ t u =
b |> $'FParsec.Primitives.(<|>)' a
inl many_satisfy_ forall t. (x : char -> bool) : parser_ string t =
x |> $'FParsec.CharParsers.manySatisfy'
inl satisfy_ forall t. (x : char -> bool) : parser_ char t =
x |> $'FParsec.CharParsers.satisfy'
inl none_of_ (x : list char) : parser_ char () =
x
|> listm'.box
|> listm'.to_array'
|> $'FParsec.CharParsers.noneOf'
inl any_of_ (x : list char) : parser_ char () =
x
|> listm'.box
|> listm'.to_array'
|> $'FParsec.CharParsers.anyOf'
inl skip_any_of_ (x : list char) : parser_ () () =
x
|> listm'.box
|> listm'.to_array'
|> $'FParsec.CharParsers.skipAnyOf'
inl between_ forall t u v x. (a : parser_ t x) (b : parser_ u x) (c : parser_ v x) : parser_ v x =
c |> $'FParsec.Primitives.between' a b
inl many_chars_ forall t. (x : parser_ char t) : parser_ string t =
x |> $'FParsec.CharParsers.manyChars'
inl many1_chars_ forall t. (x : parser_ char t) : parser_ string t =
x |> $'FParsec.CharParsers.many1Chars'
inl many_strings_ forall t. (x : parser_ string t) : parser_ string t =
x |> $'FParsec.CharParsers.manyStrings'
inl skip_any_string_ forall t. (n : i32) : parser_ () t =
n |> $'FParsec.CharParsers.skipAnyString'
inl many1_strings_ forall t. (x : parser_ string t) : parser_ string t =
x |> $'FParsec.CharParsers.many1Strings'
inl opt_ forall t u. (a : parser_ t u) : parser_ (optionm'.option' t) u =
a |> $'FParsec.Primitives.opt'
inl choice_ forall t u. (a : list (parser_ t u)) : parser_ t u =
a
|> listm'.box
|> seq.of_list'
|> $'FParsec.Primitives.choice'
inl delay_ forall t u. (fn : () -> parser_ t u) : parser_ t u =
fn |> $'FParsec.Primitives.parse.Delay'
inl peek_ forall t u. (a : parser_ t u) : parser_ char u =
$'!a.Peek ()'
inl not_followed_by_ forall t u. (a : parser_ t u) : parser_ () u =
a |> $'FParsec.Primitives.notFollowedBy'
inl sep_by_ forall t u v. (a : parser_ t v) (b : parser_ u v) : parser_ (listm'.list' t) v =
b |> $'FParsec.Primitives.sepBy' a
inl sep_by1_ forall t u v. (a : parser_ t v) (b : parser_ u v) : parser_ (listm'.list' t) v =
b |> $'FParsec.Primitives.sepBy1' a
inl sep_end_by_ forall t u v. (a : parser_ t v) (b : parser_ u v) : parser_ (listm'.list' t) v =
b |> $'FParsec.Primitives.sepEndBy' a
inl many_ forall t u. (a : parser_ t u) : parser_ (listm'.list' t) u =
a |> $'FParsec.Primitives.many'
inl many1_ forall t u. (a : parser_ t u) : parser_ (listm'.list' t) u =
a |> $'FParsec.Primitives.many1'
inl many1_satisfy_ forall t. (x : char -> bool) : parser_ string t =
x |> $'FParsec.CharParsers.many1Satisfy'
nominal parser_result'_ t u = $'FParsec.CharParsers.ParserResult<`t, `u>'
inl run_ forall t. (parser : parser_ t ()) (x : string) : parser_result'_ t () =
x |> $'FParsec.CharParsers.run' parser
union parser_result_ t u =
| Success : t * u * position_
| Failure : string * parser_error_ * u
inl parser_result_ forall t u. = function
| Success (a, b, c) => $'`(parser_result'_ t u).Success (!a, !b, !c)' : parser_result'_ t u
| Failure (a, b, c) => $'`(parser_result'_ t u).Failure (!a, !b, !c)' : parser_result'_ t u
inl parser_result'_ forall t u. (x : parser_result'_ t u) : parser_result_ t u =
$'let mutable _!x = None '
$'match !x with'
$'| FParsec.CharParsers.Success (a, b, c) -> (' : ()
$'(fun () ->'
$'(fun () ->'
(Success ((dyn $'a'), dyn $'b', dyn $'c') : _ t u) |> emit_unit
$')'
$'|> fun x -> x ()'
$') () ) | FParsec.CharParsers.Failure (a, b, c) -> (' : ()
$'(fun () ->'
$'(fun () ->'
(Failure ((dyn $'a'), dyn $'b', dyn $'c') : _ t u) |> emit_unit
$')'
$'|> fun x -> x ()'
$') () )' : ()
$'|> fun x -> _!x <- Some x'
$'match _!x with Some x -> x | None -> failwith "??? / _!x=None"'
inl parse_ parser input : result _ _ =
match input |> run_ parser |> parser_result'_ with
| Success (result, b, c) => Ok (result, c)
| Failure (error_msg, b, c) => Error (error_msg, b)
In [ ]:
//// test
inl split_args (args : string) : result (array_base (string * position_)) (string * parser_error_) =
inl esc = [ '\\'; '`' ]
inl quotes = [ '"' ]
inl special = esc ++ quotes
inl p_esc_char c =
p_char_ c >>.$ any_char_ () |>>$ fun c' => $'$"{!c}{!c'}"'
inl p_word = special |> none_of_ |>>$ sm'.obj_to_string
inl p_plain = special ++ [ ' ' ] |> none_of_ |> many1_chars_
inl p_text = p_word |> many1_strings_
inl p_esc = esc |> listm.map p_esc_char |> choice_
inl p_quoted = (p_word <|>$ p_esc) |> many_ |>>$ (seq.of_list' >> sm'.concat "")
inl p_quoted_all = p_quoted |> between_ (p_char_ '"') (p_char_ '"')
inl p_esc_root = p_esc |>>$ (fun _ => "") >>.$ (p_word |> many_) |>>$ (seq.of_list' >> sm'.concat "")
inl p_content = p_plain <|>$ p_quoted_all <|>$ p_esc_root
inl p_args = spaces1_ () |> sep_by_ p_content
args
|> parse_ p_args
|> resultm.map fun (a', b') =>
(
(
a'
|> listm'.to_array'
|> a
|> am.map fun x => x, b'
|> fun (a x : _ i32 _) => x
)
)
[
"a b c",
;[ "a"; "b"; "c" ]
"e f \"g h\" i",
;[ "e"; "f"; "g h"; "i" ]
"\"j k\" \"l\" \"m\"",
;[ "j k"; "l"; "m" ]
"s -t \"u \`\"v\`\" w\"",
;[ "s"; "-t"; "u \`\"v\`\" w" ]
"n -o \"p \\\"q\\\" r\"",
;[ "n"; "-o"; "p \\\"q\\\" r" ]
"r -s \"t \\\"u\\\"\"",
;[ "r"; "-s"; "t \\\"u\\\"" ]
$'$"x -y \\\"$z -a \'(b=\\\\\\"c-id=)[a-fA-F0-9]{{8}}\', {{ \`$_[1] + \`$d++ }}\\\""',
;[ "x"; "-y"; "$z -a '(b=\\\"c-id=)[a-fA-F0-9]{8}', { `$_[1] + `$d++ }" ]
"e -f \"$g -h '(i=`\"j-id=)[a-fA-F0-9]{8}', { `$_[1] + `$k++ }\"",
;[ "e"; "-f"; "$g -h '(i=`\"j-id=)[a-fA-F0-9]{8}', { `$_[1] + `$k++ }" ]
$'$"--l \\\\\\"\'\'\' m \'\'\'\\\\\\" "',
;[ "--l"; "''' m '''" ]
$'$"n --o --p q --r \\\"s:/t u/v.w\\\" --x \\\"y:/z.a\\\" --b c.d \\\"\\\\e{{f-g}}\\\" h.i \\\"j (k)\\\""',
;[ "n"; "--o"; "--p"; "q"; "--r"; "s:/t u/v.w"; "--x"; "y:/z.a"; "--b"; "c.d"; "\\e{f-g}"; "h.i"; "j (k)" ]
$'\@$"l ""m n:\\o.p"""',
;[ "l"; "m n:\\o.p" ]
]
|> listm.rev
|> listm.map fun input, expected =>
input
|> split_args
|> fun x =>
try
fun () =>
($'$"\ninput: {!input}"' : string)
|> console.write_line
x
|> resultm.get
|> am'.map_base fst
|> _assert_eq' expected
false
fun ex =>
($'$"error / expected: %A{!expected} / ex: %A{!ex}"' : string)
|> console.write_line
Some true
|> optionm.value
|> listm'.filter id
|> function
| [] => ()
| x => failwith $'$"{!x}"'
input: a b c { name = __assert_eq'; actual = [|"a"; "b"; "c"|]; expected = [|"a"; "b"; "c"|] } input: e f "g h" i { name = __assert_eq'; actual = [|"e"; "f"; "g h"; "i"|]; expected = [|"e"; "f"; "g h"; "i"|] } input: "j k" "l" "m" { name = __assert_eq'; actual = [|"j k"; "l"; "m"|]; expected = [|"j k"; "l"; "m"|] } input: s -t "u `"v`" w" { name = __assert_eq'; actual = [|"s"; "-t"; "u `"v`" w"|]; expected = [|"s"; "-t"; "u `"v`" w"|] } input: n -o "p \"q\" r" { name = __assert_eq'; actual = [|"n"; "-o"; "p \"q\" r"|]; expected = [|"n"; "-o"; "p \"q\" r"|] } input: r -s "t \"u\"" { name = __assert_eq'; actual = [|"r"; "-s"; "t \"u\""|]; expected = [|"r"; "-s"; "t \"u\""|] } input: x -y "$z -a '(b=\"c-id=)[a-fA-F0-9]{8}', { `$_[1] + `$d++ }" { name = __assert_eq'; actual = [|"x"; "-y"; "$z -a '(b=\"c-id=)[a-fA-F0-9]{8}', { `$_[1] + `$d++ }"|]; expected = [|"x"; "-y"; "$z -a '(b=\"c-id=)[a-fA-F0-9]{8}', { `$_[1] + `$d++ }"|] } input: e -f "$g -h '(i=`"j-id=)[a-fA-F0-9]{8}', { `$_[1] + `$k++ }" { name = __assert_eq'; actual = [|"e"; "-f"; "$g -h '(i=`"j-id=)[a-fA-F0-9]{8}', { `$_[1] + `$k++ }"|]; expected = [|"e"; "-f"; "$g -h '(i=`"j-id=)[a-fA-F0-9]{8}', { `$_[1] + `$k++ }"|] } input: --l \"''' m '''\" { name = __assert_eq'; actual = [|"--l"; "''' m '''"|]; expected = [|"--l"; "''' m '''"|] } input: n --o --p q --r "s:/t u/v.w" --x "y:/z.a" --b c.d "\e{f-g}" h.i "j (k)" { name = __assert_eq'; actual = [|"n"; "--o"; "--p"; "q"; "--r"; "s:/t u/v.w"; "--x"; "y:/z.a"; "--b"; "c.d"; "\e{f-g}"; "h.i"; "j (k)"|]; expected = [|"n"; "--o"; "--p"; "q"; "--r"; "s:/t u/v.w"; "--x"; "y:/z.a"; "--b"; "c.d"; "\e{f-g}"; "h.i"; "j (k)"|] } input: l "m n:\o.p" { name = __assert_eq'; actual = [|"l"; "m n:\o.p"|]; expected = [|"l"; "m n:\o.p"|] }
parsing¶
range¶
In [ ]:
type range =
{
from : int
to : int
}
position¶
In [ ]:
type position =
{
line : int
col : int
}
parser_state¶
In [ ]:
nominal parser_state =
{
line_text : sm'.string_builder
position : position
}
parser¶
In [ ]:
type parser t = string * parser_state -> result (t * string * parser_state) string
parse¶
In [ ]:
inl parse forall t. (p : parser t) (input : string) : result (t * string * parser_state) string =
inl input =
input
|> optionm'.of_obj
|> optionm'.default_value' ""
p (input, { line_text = "" |> sm'.string_builder; position = { line = 1; col = 1 } } |> parser_state)
inc¶
In [ ]:
inl inc (parser_state s) = function
| '\n' => { line = s.position.line + 1; col = 1 }
| _ => { s.position with col = s.position.col + 1 }.position
update¶
In [ ]:
inl update result s =
(s, result |> sm'.to_char_list)
||> listm.fold fun (parser_state s as s') c =>
{ s with
position = c |> inc s'
line_text =
match c with
| '\n' => s.line_text |> sm'.builder_clear
| c => s.line_text |> sm'.builder_append $c
} |> parser_state
any_char¶
In [ ]:
inl any_char () : parser char = function
| "", s => "parsing.any_char / unexpected end of input / " ++# ({ s } |> sm'.format) |> Error
| x, s =>
inl first_char = x |> sm'.index 0i32
Ok (
first_char,
x |> sm'.range (am'.Start 1i32) (am'.End eval),
s |> update $first_char
)
In [ ]:
//// test
///! gleam
///! fsharp
///! cuda
///! typescript
"abc"
|> parse (any_char ())
|> resultm.get
|> sm'.format_debug
|> _assert_eq (
('a', "bc", { line_text = "a" |> sm'.string_builder; position = { line = 1i32; col = 2i32 } })
|> sm'.format_debug
)
.py output (Python): { name = __assert_eq; actual = ('a', 'bc', a, 1, 2); expected = ('a', 'bc', a, 1, 2) } .ts output: { name = __assert_eq; actual = a,bc,a,1,2; expected = a,bc,a,1,2 } .gleam output (Gleam): { name = __assert_eq; actual = #("a", "bc", "a", 1, 2); expected = #("a", "bc", "a", 1, 2) }
.fsx output: { name = __assert_eq; actual = struct ('a', "bc", a, 1, 2); expected = struct ('a', "bc", a, 1, 2) }
In [ ]:
//// test
"abc"
|> parse_ (any_char_ ())
|> resultm.get
|> sm'.format_debug
|> _assert_eq' (('a', ($'FParsec.Position (null, 0, 1, 2)' : position_)) |> sm'.format_debug)
{ name = __assert_eq'; actual = struct ('a', (Ln: 1, Col: 2)); expected = struct ('a', (Ln: 1, Col: 2)) }
p_char¶
In [ ]:
inl p_char (c : char) : parser char = function
| "", s => "parsing.p_char / unexpected end of input / " ++# ({ c s } |> sm'.format) |> Error
| input, (parser_state ({ line_text position = { line col } } as s) as s') =>
inl first_char = input |> sm'.index 0i32
// [
// "parsing.p_char"
// " / c: "; $c
// " / input: "; input
// " / s: "; { s } |> sm'.format
// ]
// |> sm'.concat_list ""
// |> console.write_line
if first_char = c then
Ok (
first_char,
input |> sm'.range (am'.Start 1i32) (am'.End eval),
s' |> update $first_char
)
else
inl message : string =
inl rest =
input
|> sm'.range
(am'.Start 0i32)
(am'.End fun l =>
match (input |> sm'.index_of "\n") - 1 with
| -2 => l () + 1
| i => i + 1
)
"parsing.p_char / "
++# ({ expected = c; line col } |> sm'.format)
++# "\n" ++# $line_text ++# rest
inl pointer_line = (" " |> sm'.replicate (col - 1)) ++# "^"
message ++# "\n" ++# pointer_line ++# "\n"
|> Error
In [ ]:
//// test
///! gleam
///! fsharp
///! cuda
///! typescript
"abc"
|> parse (p_char 'a')
|> resultm.get
|> sm'.format_debug
|> _assert_eq (
('a', "bc", { line_text = "a" |> sm'.string_builder; position = { line = 1i32; col = 2i32 } })
|> sm'.format_debug
)
.py output (Python): { name = __assert_eq; actual = ('a', 'bc', a, 1, 2); expected = ('a', 'bc', a, 1, 2) } .ts output: { name = __assert_eq; actual = a,bc,a,1,2; expected = a,bc,a,1,2 } .gleam output (Gleam): { name = __assert_eq; actual = #("a", "bc", "a", 1, 2); expected = #("a", "bc", "a", 1, 2) }
.fsx output: { name = __assert_eq; actual = struct ('a', "bc", a, 1, 2); expected = struct ('a', "bc", a, 1, 2) }
In [ ]:
//// test
"abc"
|> parse_ (p_char_ 'a')
|> resultm.get
|> sm'.format_debug
|> _assert_eq' (('a', ($'FParsec.Position (null, 0, 1, 2)' : position_)) |> sm'.format_debug)
{ name = __assert_eq'; actual = struct ('a', (Ln: 1, Col: 2)); expected = struct ('a', (Ln: 1, Col: 2)) }
any_string¶
In [ ]:
inl any_string length : parser string = fun input, s =>
if sm'.length input < length
then "parsing.any_string / unexpected end of input / " ++# ({ s } |> sm'.format) |> Error
else
inl result = input |> sm'.range (am'.Start 0i32) (am'.End fun _ => length)
Ok (
result,
input |> sm'.range (am'.Start length) (am'.End eval),
s |> update result
)
In [ ]:
//// test
///! gleam
///! fsharp
///! cuda
///! typescript
"abcdef"
|> parse (any_string 3i32)
|> resultm.get
|> sm'.format_debug
|> _assert_eq (
("abc", "def", { line_text = "abc" |> sm'.string_builder; position = { line = 1i32; col = 4i32 } })
|> sm'.format_debug
)
.py output (Python): { name = __assert_eq; actual = ('abc', 'def', abc, 1, 4); expected = ('abc', 'def', abc, 1, 4) } .ts output: { name = __assert_eq; actual = abc,def,abc,1,4; expected = abc,def,abc,1,4 } .gleam output (Gleam): { name = __assert_eq; actual = #("abc", "def", "abc", 1, 4); expected = #("abc", "def", "abc", 1, 4) }
.fsx output: { name = __assert_eq; actual = struct ("abc", "def", abc, 1, 4); expected = struct ("abc", "def", abc, 1, 4) }
In [ ]:
//// test
"abcdef"
|> parse_ (any_string__ 3)
|> resultm.get
|> sm'.obj_to_string
|> _assert_eq' (("abc", ($'FParsec.Position (null, 0, 1, 4)' : position_)) |> sm'.obj_to_string)
{ name = __assert_eq'; actual = (abc, (Ln: 1, Col: 4)); expected = (abc, (Ln: 1, Col: 4)) }
skip_any_string¶
In [ ]:
inl skip_any_string length : parser () = fun input, s =>
if sm'.length input < length
then "parsing.skip_any_string / unexpected end of input / " ++# ({ s } |> sm'.format) |> Error
else
Ok (
(),
input |> sm'.range (am'.Start length) (am'.End eval),
s |> update (input |> sm'.range (am'.Start 0i32) (am'.End fun _ => length))
)
In [ ]:
//// test
///! gleam
///! fsharp
///! cuda
///! typescript
"abcdef"
|> parse (skip_any_string 3i32)
|> resultm.get
|> sm'.format_debug
|> _assert_eq (
((), "def", { line_text = "abc" |> sm'.string_builder; position = { line = 1i32; col = 4i32 } })
|> sm'.format_debug
)
.py output (Python): { name = __assert_eq; actual = ('def', abc, 1, 4); expected = ('def', abc, 1, 4) } .ts output: { name = __assert_eq; actual = def,abc,1,4; expected = def,abc,1,4 } .gleam output (Gleam): { name = __assert_eq; actual = #("def", "abc", 1, 4); expected = #("def", "abc", 1, 4) }
.fsx output: { name = __assert_eq; actual = struct ("def", abc, 1, 4); expected = struct ("def", abc, 1, 4) }
(>>.)¶
In [ ]:
inl (>>.) forall t u. (a : parser t) (b : parser u) : parser u = fun input, s =>
match a (input, s) with
| Ok (_, rest, s) => b (rest, s)
| Error e => Error e
In [ ]:
//// test
///! gleam
///! fsharp
///! cuda
///! typescript
"abc\ndef\nghi"
|> parse (skip_any_string 5i32 >>. p_char 'a')
|> _assert_eq (Error "parsing.p_char / { expected = a; line = 2; col = 2 }\ndef\n ^\n")
.py output (Python): { name = __assert_eq; actual = US1_1(v0='parsing.p_char / { expected = a; line = 2; col = 2 }\ndef\n ^\n'); expected = US1_1(v0='parsing.p_char / { expected = a; line = 2; col = 2 }\ndef\n ^\n') } .ts output: { name = __assert_eq; actual = US1_1 (parsing.p_char / { expected = a; line = 2; col = 2 } def ^ ); expected = US1_1 (parsing.p_char / { expected = a; line = 2; col = 2 } def ^ ) } .gleam output (Gleam): { name = __assert_eq; actual = Us1i1("parsing.p_char / { expected = a; line = 2; col = 2 }\ndef\n ^\n"); expected = Us1i1("parsing.p_char / { expected = a; line = 2; col = 2 }\ndef\n ^\n") }
.fsx output: { name = __assert_eq; actual = US1_1 "parsing.p_char / { expected = a; line = 2; col = 2 } def ^ "; expected = US1_1 "parsing.p_char / { expected = a; line = 2; col = 2 } def ^ " }
(>>.)¶
In [ ]:
inl (.>>) forall t u. (a : parser t) (b : parser u) : parser t = fun input, s =>
match a (input, s) with
| Ok (result, rest, s) =>
b (rest, s)
|> resultm.map fun _, rest, s =>
result, rest, s
| Error e => Error e
(.>>.)¶
In [ ]:
inl (.>>.) forall t u. (a : parser t) (b : parser u) : parser (t * u) = fun input, s =>
match a (input, s) with
| Ok (result_a, rest, s) =>
b (rest, s)
|> resultm.map fun result_b, rest, s =>
(result_a, result_b), rest, s
| Error e => Error e
(>>%)¶
In [ ]:
inl (>>%) forall t u. (a : parser t) (b : u) : parser u =
a >> resultm.map fun _, rest, s =>
b, rest, s
In [ ]:
//// test
///! gleam
///! fsharp
///! cuda
///! typescript
"abc"
|> parse (p_char 'a' >>. p_char 'b')
|> resultm.get
|> sm'.format_debug
|> _assert_eq (
('b', "c", { line_text = "ab" |> sm'.string_builder; position = { line = 1i32; col = 3i32 } })
|> sm'.format_debug
)
.py output (Python): { name = __assert_eq; actual = ('b', 'c', ab, 1, 3); expected = ('b', 'c', ab, 1, 3) } .ts output: { name = __assert_eq; actual = b,c,ab,1,3; expected = b,c,ab,1,3 } .gleam output (Gleam): { name = __assert_eq; actual = #("b", "c", "ab", 1, 3); expected = #("b", "c", "ab", 1, 3) }
.fsx output: { name = __assert_eq; actual = struct ('b', "c", ab, 1, 3); expected = struct ('b', "c", ab, 1, 3) }
In [ ]:
//// test
"abc"
|> parse_ (p_char_ 'a' >>.$ p_char_ 'b')
|> resultm.get
|> sm'.obj_to_string
|> _assert_eq' (('b', ($'FParsec.Position (null, 0, 1, 3)' : position_)) |> sm'.obj_to_string)
{ name = __assert_eq'; actual = (b, (Ln: 1, Col: 3)); expected = (b, (Ln: 1, Col: 3)) }
In [ ]:
//// test
"abc\ndef\nghi"
|> parse_ (skip_any_string_ 5 >>.$ p_char_ 'a')
|> resultm.unwrap_err
|> sm'.obj_to_string
|> sm'.replace "\r\n" "\n"
|> _assert_eq "(Error in Ln: 2 Col: 2\ndef\n ^\nExpecting: 'a'\n, Error in Ln: 2 Col: 2\nExpecting: 'a'\n)"
{ name = __assert_eq; actual = (Error in Ln: 2 Col: 2 def ^ Expecting: 'a' , Error in Ln: 2 Col: 2 Expecting: 'a' ); expected = (Error in Ln: 2 Col: 2 def ^ Expecting: 'a' , Error in Ln: 2 Col: 2 Expecting: 'a' ) }
none_of¶
In [ ]:
inl none_of (chars : list char) x =
inl chars' () : string =
backend_switch {
Gleam = fun () => chars |> listm'.box |> sm'.format
Fsharp = fun () => chars |> listm'.box |> listm'.to_array' |> sm'.format
Python = fun () => chars |> listm'.box |> listm'.to_array' |> sm'.format
}
match x with
| "", s =>
("parsing.none_of / unexpected end of input / " ++# ({ chars = chars' (); s } |> sm'.format)) |> Error
| x, s =>
inl first_char = x |> sm'.index 0i32
if chars |> listm'.exists' ((=) first_char) |> not then
Ok (
first_char,
x |> sm'.range (am'.Start 1i32) (am'.End eval),
s |> update $first_char
)
else
"parsing.none_of / unexpected char / " ++# ({ first_char chars = chars' (); s } |> sm'.format)
|> Error
In [ ]:
//// test
///! gleam
///! fsharp
///! cuda
///! typescript
"abc"
|> parse (none_of ['a'; 'b'; 'c'])
|> _assert_eq (
backend_switch {
Gleam = fun () =>
"parsing.none_of / unexpected char / "
++# "{ first_char = a; chars = [\"a\", \"b\", \"c\"]; s = #(\"\", 1, 1) }"
Fsharp = fun () =>
run_target function
| TypeScript _ => fun () =>
join
"parsing.none_of / unexpected char / "
++# "{ first_char = a; chars = a,b,c; s = ,1,1 }"
| _ => fun () =>
join
"parsing.none_of / unexpected char / "
++# "{ first_char = a; chars = [|'a'; 'b'; 'c'|]; s = struct (, 1, 1) }"
Python = fun () =>
"parsing.none_of / unexpected char / "
++# "{ first_char = a; chars = ['a' 'b' 'c']; s = (, 1, 1) }"
}
|> Error
)
"def"
|> parse (none_of ['a'; 'b'; 'c'])
|> resultm.get
|> sm'.format_debug
|> _assert_eq (
('d', "ef", { line_text = "d" |> sm'.string_builder; position = { line = 1i32; col = 2i32 } })
|> sm'.format_debug
)
.py output (Python): { name = __assert_eq; actual = US0_1(v0="parsing.none_of / unexpected char / { first_char = a; chars = ['a' 'b' 'c']; s = (, 1, 1) }"); expected = US0_1(v0="parsing.none_of / unexpected char / { first_char = a; chars = ['a' 'b' 'c']; s = (, 1, 1) }") } { name = __assert_eq; actual = ('d', 'ef', d, 1, 2); expected = ('d', 'ef', d, 1, 2) } .ts output: { name = __assert_eq; actual = US0_1 (parsing.none_of / unexpected char / { first_char = a; chars = a,b,c; s = ,1,1 }); expected = US0_1 (parsing.none_of / unexpected char / { first_char = a; chars = a,b,c; s = ,1,1 }) } { name = __assert_eq; actual = d,ef,d,1,2; expected = d,ef,d,1,2 } .gleam output (Gleam): { name = __assert_eq; actual = Us0i1("parsing.none_of / unexpected char / { first_char = a; chars = [\"a\", \"b\", \"c\"]; s = #(\"\", 1, 1) }"); expected = Us0i1("parsing.none_of / unexpected char / { first_char = a; chars = [\"a\", \"b\", \"c\"]; s = #(\"\", 1, 1) }") } { name = __assert_eq; actual = #("d", "ef", "d", 1, 2); expected = #("d", "ef", "d", 1, 2) }
.fsx output: { name = __assert_eq; actual = US0_1 "parsing.none_of / unexpected char / { first_char = a; chars = [|'a'; 'b'; 'c'|]; s = struct (, 1, 1) }"; expected = US0_1 "parsing.none_of / unexpected char / { first_char = a; chars = [|'a'; 'b'; 'c'|]; s = struct (, 1, 1) }" } { name = __assert_eq; actual = struct ('d', "ef", d, 1, 2); expected = struct ('d', "ef", d, 1, 2) }
In [ ]:
//// test
"abc"
|> parse_ (none_of_ ['a'; 'b'; 'c'])
|> resultm.unwrap_err
|> sm'.obj_to_string
|> sm'.replace "\r\n" "\n"
|> _assert_eq ($'"(Error in Ln: 1 Col: 1\nabc\n^\nExpecting: any char not in ‘abc’\n, Error in Ln: 1 Col: 1\nExpecting: any char not in ‘abc’\n)"')
"def"
|> parse_ (none_of_ ['a'; 'b'; 'c'])
|> resultm.get
|> sm'.obj_to_string
|> _assert_eq' (('d', ($'FParsec.Position (null, 0, 1, 2)' : position_)) |> sm'.obj_to_string)
{ name = __assert_eq; actual = (Error in Ln: 1 Col: 1 abc ^ Expecting: any char not in ‘abc’ , Error in Ln: 1 Col: 1 Expecting: any char not in ‘abc’ ); expected = (Error in Ln: 1 Col: 1 abc ^ Expecting: any char not in ‘abc’ , Error in Ln: 1 Col: 1 Expecting: any char not in ‘abc’ ) } { name = __assert_eq'; actual = (d, (Ln: 1, Col: 2)); expected = (d, (Ln: 1, Col: 2)) }
(<|>)¶
In [ ]:
inl (<|>) forall t. (a : parser t) (b : parser t) : parser t = fun input, s =>
match a (input, s) with
| Ok _ as result => result
| Error _ => b (input, s)
In [ ]:
//// test
///! gleam
///! fsharp
///! cuda
///! typescript
"abc"
|> parse (p_char 'a' <|> p_char 'b')
|> resultm.get
|> sm'.format_debug
|> _assert_eq (
('a', "bc", { line_text = "a" |> sm'.string_builder; position = { line = 1i32; col = 2i32 } })
|> sm'.format_debug
)
"cba"
|> parse (p_char 'a' <|> p_char 'b')
|> _assert_eq (Error "parsing.p_char / { expected = b; line = 1; col = 1 }\ncba\n^\n")
.py output (Python): { name = __assert_eq; actual = ('a', 'bc', a, 1, 2); expected = ('a', 'bc', a, 1, 2) } { name = __assert_eq; actual = US0_1(v0='parsing.p_char / { expected = b; line = 1; col = 1 }\ncba\n^\n'); expected = US0_1(v0='parsing.p_char / { expected = b; line = 1; col = 1 }\ncba\n^\n') } .ts output: { name = __assert_eq; actual = a,bc,a,1,2; expected = a,bc,a,1,2 } { name = __assert_eq; actual = US0_1 (parsing.p_char / { expected = b; line = 1; col = 1 } cba ^ ); expected = US0_1 (parsing.p_char / { expected = b; line = 1; col = 1 } cba ^ ) } .gleam output (Gleam): { name = __assert_eq; actual = #("a", "bc", "a", 1, 2); expected = #("a", "bc", "a", 1, 2) } { name = __assert_eq; actual = Us0i1("parsing.p_char / { expected = b; line = 1; col = 1 }\ncba\n^\n"); expected = Us0i1("parsing.p_char / { expected = b; line = 1; col = 1 }\ncba\n^\n") }
.fsx output: { name = __assert_eq; actual = struct ('a', "bc", a, 1, 2); expected = struct ('a', "bc", a, 1, 2) } { name = __assert_eq; actual = US0_1 "parsing.p_char / { expected = b; line = 1; col = 1 } cba ^ "; expected = US0_1 "parsing.p_char / { expected = b; line = 1; col = 1 } cba ^ " }
(|>>)¶
In [ ]:
inl (|>>) p f : parser _ =
p >> resultm.map fun result, rest =>
f result, rest
In [ ]:
//// test
///! gleam
///! fsharp
///! cuda
///! typescript
"abc"
|> parse (p_char 'a' |>> sm'.char_to_upper)
|> resultm.get
|> sm'.format_debug
|> _assert_eq (
('A', "bc", { line_text = "a" |> sm'.string_builder; position = { line = 1i32; col = 2i32 } })
|> sm'.format_debug
)
.py output (Python): { name = __assert_eq; actual = ('A', 'bc', a, 1, 2); expected = ('A', 'bc', a, 1, 2) } .ts output: { name = __assert_eq; actual = A,bc,a,1,2; expected = A,bc,a,1,2 } .gleam output (Gleam): { name = __assert_eq; actual = #("A", "bc", "a", 1, 2); expected = #("A", "bc", "a", 1, 2) }
.fsx output: { name = __assert_eq; actual = struct ('A', "bc", a, 1, 2); expected = struct ('A', "bc", a, 1, 2) }
many¶
In [ ]:
// inl many p : parser (list _) = fun input =>
inl many forall b c. (p : _ -> _ (b * _ * _) c) : parser (list _) = fun input =>
// let rec 루프 acc input =
let rec 루프 forall a.
(acc : list b)
(input : string * parser_state)
: result (list b * string * parser_state) a
=
match p input with
| Ok (result, rest) => 루프 (result :: acc) rest
| Error _ => Ok (acc |> listm.rev, input)
루프 [] input
In [ ]:
//// test
///! gleam
///! fsharp
///! cuda
///! typescript
"aaabbc"
|> parse (many (p_char 'a' <|> p_char 'b'))
|> resultm.get
|> sm'.format_debug
|> _assert_eq (
(
['a'; 'a'; 'a'; 'b'; 'b'],
"c",
{ line_text = "aaabb" |> sm'.string_builder; position = { line = 1i32; col = 6i32 } }
)
|> sm'.format_debug
)
.py output (Python): { name = __assert_eq; actual = (UH0_1(v0='a', v1=UH0_1(v0='a', v1=UH0_1(v0='a', v1=UH0_1(v0='b', v1=UH0_1(v0='b', v1=UH0_0()))))), 'c', aaabb, 1, 6); expected = (UH0_1(v0='a', v1=UH0_1(v0='a', v1=UH0_1(v0='a', v1=UH0_1(v0='b', v1=UH0_1(v0='b', v1=UH0_0()))))), 'c', aaabb, 1, 6) } .ts output: { name = __assert_eq; actual = UH0_1 (a, UH0_1 (a, UH0_1 (a, UH0_1 (b, UH0_1 (b, UH0_0))))),c,aaabb,1,6; expected = UH0_1 (a, UH0_1 (a, UH0_1 (a, UH0_1 (b, UH0_1 (b, UH0_0))))),c,aaabb,1,6 } .gleam output (Gleam): { name = __assert_eq; actual = #(Uh0i1("a", Uh0i1("a", Uh0i1("a", Uh0i1("b", Uh0i1("b", Uh0i0))))), "c", "aaabb", 1, 6); expected = #(Uh0i1("a", Uh0i1("a", Uh0i1("a", Uh0i1("b", Uh0i1("b", Uh0i0))))), "c", "aaabb", 1, 6) }
.fsx output: { name = __assert_eq; actual = struct (UH0_1 ('a', UH0_1 ('a', UH0_1 ('a', UH0_1 ('b', UH0_1 ('b', UH0_0))))), "c", aaabb, 1, 6); expected = struct (UH0_1 ('a', UH0_1 ('a', UH0_1 ('a', UH0_1 ('b', UH0_1 ('b', UH0_0))))), "c", aaabb, 1, 6) }
many1_chars¶
In [ ]:
inl many1_chars p : parser string =
p >> resultm.map fun first_result, rest =>
let rec 루프 acc input =
match p input with
| Ok (result, rest) => rest |> 루프 (acc ++# $result)
| Error _ => acc, input
rest |> 루프 $first_result
In [ ]:
//// test
///! gleam
///! fsharp
///! cuda
///! typescript
"aaabbc"
|> parse (many1_chars (p_char 'a' <|> p_char 'b'))
|> resultm.get
|> sm'.format_debug
|> _assert_eq (
("aaabb", "c", { line_text = "aaabb" |> sm'.string_builder; position = { line = 1i32; col = 6i32 } })
|> sm'.format_debug
)
.py output (Python): { name = __assert_eq; actual = ('aaabb', 'c', aaabb, 1, 6); expected = ('aaabb', 'c', aaabb, 1, 6) } .ts output: { name = __assert_eq; actual = aaabb,c,aaabb,1,6; expected = aaabb,c,aaabb,1,6 } .gleam output (Gleam): { name = __assert_eq; actual = #("aaabb", "c", "aaabb", 1, 6); expected = #("aaabb", "c", "aaabb", 1, 6) }
.fsx output: { name = __assert_eq; actual = struct ("aaabb", "c", aaabb, 1, 6); expected = struct ("aaabb", "c", aaabb, 1, 6) }
many_chars¶
In [ ]:
inl many_chars p : parser string = fun input =>
match many1_chars p input with
| Ok (result, rest) => Ok (result, rest)
| Error e => Ok ("", input)
many_chars_till¶
In [ ]:
inl many_chars_till p end_p : parser string = fun input =>
match end_p input with
| Ok _ => Ok ("", input)
| Error _ => many_chars p input
many1¶
In [ ]:
inl many1 p : parser (list _) =
p >> resultm.map fun first_result, rest =>
let rec 루프 acc input =
match p input with
| Ok (result, rest) => 루프 (result :: acc) rest
| Error _ => acc |> listm.rev, input
루프 [ first_result ] rest
In [ ]:
//// test
///! gleam
///! fsharp
///! cuda
///! typescript
"aaabbc"
|> parse (many1 (p_char 'a' <|> p_char 'b'))
|> resultm.get
|> sm'.format_debug
|> _assert_eq (
(
['a'; 'a'; 'a'; 'b'; 'b'],
"c",
{ line_text = "aaabb" |> sm'.string_builder; position = { line = 1i32; col = 6i32 } }
)
|> sm'.format_debug
)
"bcc"
|> parse (many1 (p_char 'a' <|> p_char 'b'))
|> resultm.get
|> sm'.format_debug
|> _assert_eq (
(['b'], "cc", { line_text = "b" |> sm'.string_builder; position = { line = 1i32; col = 2i32 } })
|> sm'.format_debug
)
"cba"
|> parse (many1 (p_char 'a' <|> p_char 'b'))
|> _assert_eq (Error "parsing.p_char / { expected = b; line = 1; col = 1 }\ncba\n^\n")
.py output (Python): { name = __assert_eq; actual = (UH0_1(v0='a', v1=UH0_1(v0='a', v1=UH0_1(v0='a', v1=UH0_1(v0='b', v1=UH0_1(v0='b', v1=UH0_0()))))), 'c', aaabb, 1, 6); expected = (UH0_1(v0='a', v1=UH0_1(v0='a', v1=UH0_1(v0='a', v1=UH0_1(v0='b', v1=UH0_1(v0='b', v1=UH0_0()))))), 'c', aaabb, 1, 6) } { name = __assert_eq; actual = (UH0_1(v0='b', v1=UH0_0()), 'cc', b, 1, 2); expected = (UH0_1(v0='b', v1=UH0_0()), 'cc', b, 1, 2) } { name = __assert_eq; actual = US1_1(v0='parsing.p_char / { expected = b; line = 1; col = 1 }\ncba\n^\n'); expected = US1_1(v0='parsing.p_char / { expected = b; line = 1; col = 1 }\ncba\n^\n') } .ts output: { name = __assert_eq; actual = UH0_1 (a, UH0_1 (a, UH0_1 (a, UH0_1 (b, UH0_1 (b, UH0_0))))),c,aaabb,1,6; expected = UH0_1 (a, UH0_1 (a, UH0_1 (a, UH0_1 (b, UH0_1 (b, UH0_0))))),c,aaabb,1,6 } { name = __assert_eq; actual = UH0_1 (b, UH0_0),cc,b,1,2; expected = UH0_1 (b, UH0_0),cc,b,1,2 } { name = __assert_eq; actual = US1_1 (parsing.p_char / { expected = b; line = 1; col = 1 } cba ^ ); expected = US1_1 (parsing.p_char / { expected = b; line = 1; col = 1 } cba ^ ) } .gleam output (Gleam): { name = __assert_eq; actual = #(Uh0i1("a", Uh0i1("a", Uh0i1("a", Uh0i1("b", Uh0i1("b", Uh0i0))))), "c", "aaabb", 1, 6); expected = #(Uh0i1("a", Uh0i1("a", Uh0i1("a", Uh0i1("b", Uh0i1("b", Uh0i0))))), "c", "aaabb", 1, 6) } { name = __assert_eq; actual = #(Uh0i1("b", Uh0i0), "cc", "b", 1, 2); expected = #(Uh0i1("b", Uh0i0), "cc", "b", 1, 2) } { name = __assert_eq; actual = Us1i1("parsing.p_char / { expected = b; line = 1; col = 1 }\ncba\n^\n"); expected = Us1i1("parsing.p_char / { expected = b; line = 1; col = 1 }\ncba\n^\n") }
.fsx output: { name = __assert_eq; actual = struct (UH0_1 ('a', UH0_1 ('a', UH0_1 ('a', UH0_1 ('b', UH0_1 ('b', UH0_0))))), "c", aaabb, 1, 6); expected = struct (UH0_1 ('a', UH0_1 ('a', UH0_1 ('a', UH0_1 ('b', UH0_1 ('b', UH0_0))))), "c", aaabb, 1, 6) } { name = __assert_eq; actual = struct (UH0_1 ('b', UH0_0), "cc", b, 1, 2); expected = struct (UH0_1 ('b', UH0_0), "cc", b, 1, 2) } { name = __assert_eq; actual = US1_1 "parsing.p_char / { expected = b; line = 1; col = 1 } cba ^ "; expected = US1_1 "parsing.p_char / { expected = b; line = 1; col = 1 } cba ^ " }
many1_strings¶
In [ ]:
inl many1_strings p : parser string =
many1 p >> resultm.map fun results, rest =>
results
|> listm.map sm'.obj_to_string
|> listm'.box
|> seq.of_list'
|> sm'.concat "",
rest
In [ ]:
//// test
///! gleam
///! fsharp
///! cuda
///! typescript
"aaabbc"
|> parse (many1_strings (p_char 'a' <|> p_char 'b'))
|> resultm.get
|> sm'.format_debug
|> _assert_eq (
("aaabb", "c", { line_text = "aaabb" |> sm'.string_builder; position = { line = 1i32; col = 6i32 } })
|> sm'.format_debug
)
.py output (Python): { name = __assert_eq; actual = ('aaabb', 'c', aaabb, 1, 6); expected = ('aaabb', 'c', aaabb, 1, 6) } .ts output: { name = __assert_eq; actual = aaabb,c,aaabb,1,6; expected = aaabb,c,aaabb,1,6 } .gleam output (Gleam): { name = __assert_eq; actual = #("aaabb", "c", "aaabb", 1, 6); expected = #("aaabb", "c", "aaabb", 1, 6) }
.fsx output: { name = __assert_eq; actual = struct ("aaabb", "c", aaabb, 1, 6); expected = struct ("aaabb", "c", aaabb, 1, 6) }
many_strings¶
In [ ]:
inl many_strings p : parser string = fun input =>
match many p input with
| Ok (results, rest) =>
Ok (results |> listm.map sm'.obj_to_string |> listm'.box |> seq.of_list' |> sm'.concat "", rest)
| Error e => Ok ("", input)
choice¶
In [ ]:
// inl choice parsers : parser _ = fun input =>
inl choice forall t. parsers : parser t = fun input =>
// let rec 루프 = function
let rec 루프 forall a. (x : list (string * parser_state -> result a string)) : result a string =
match x with
| [] => Error "parsing.choice / no parsers succeeded"
| p :: ps =>
match p input with
| Ok _ as result => result
| Error _ => 루프 ps
루프 parsers
In [ ]:
//// test
///! gleam
///! fsharp
///! cuda
///! typescript
"bca"
|> parse (choice [ p_char 'a'; p_char 'b'; p_char 'c' ])
|> resultm.get
|> sm'.format_debug
|> _assert_eq (
('b', "ca", { line_text = "b" |> sm'.string_builder; position = { line = 1i32; col = 2i32 } })
|> sm'.format_debug
)
"cba"
|> parse (choice [ p_char 'a'; p_char 'b'; p_char 'c' ])
|> resultm.get
|> sm'.format_debug
|> _assert_eq (
('c', "ba", { line_text = "c" |> sm'.string_builder; position = { line = 1i32; col = 2i32 } })
|> sm'.format_debug
)
.py output (Python): { name = __assert_eq; actual = ('b', 'ca', b, 1, 2); expected = ('b', 'ca', b, 1, 2) } { name = __assert_eq; actual = ('c', 'ba', c, 1, 2); expected = ('c', 'ba', c, 1, 2) } .ts output: { name = __assert_eq; actual = b,ca,b,1,2; expected = b,ca,b,1,2 } { name = __assert_eq; actual = c,ba,c,1,2; expected = c,ba,c,1,2 } .gleam output (Gleam): { name = __assert_eq; actual = #("b", "ca", "b", 1, 2); expected = #("b", "ca", "b", 1, 2) } { name = __assert_eq; actual = #("c", "ba", "c", 1, 2); expected = #("c", "ba", "c", 1, 2) }
.fsx output: { name = __assert_eq; actual = struct ('b', "ca", b, 1, 2); expected = struct ('b', "ca", b, 1, 2) } { name = __assert_eq; actual = struct ('c', "ba", c, 1, 2); expected = struct ('c', "ba", c, 1, 2) }
between¶
In [ ]:
inl between p_open p_close p_content : parser _ = fun input =>
match p_open input with
| Ok (_, rest1) =>
match p_content rest1 with
| Ok (result, rest2) =>
match p_close rest2 with
| Ok (_, rest3) => Ok (result, rest3)
| Error e =>
"parsing.between / expected closing delimiter / " ++# ({ e input rest1 rest2 } |> sm'.format)
|> Error
| Error _ => Error "parsing.between / expected content"
| Error e => Error e
In [ ]:
//// test
"[aaabb"
|> parse_ (between_ (p_char_ '[') (p_char_ ']') (many1_chars_ (p_char_ 'a' <|>$ p_char_ 'b')))
|> resultm.unwrap_err
|> sm'.format_debug
struct ("Error in Ln: 1 Col: 7 [aaabb ^ Note: The error occurred at the end of the input stream. Expecting: ']', 'a' or 'b' ", Error in Ln: 1 Col: 7 Expecting: ']', 'a' or 'b' )
In [ ]:
//// test
///! gleam
///! fsharp
///! cuda
///! typescript
"[aaabb]"
|> parse (between (p_char '[') (p_char ']') (many1_chars (p_char 'a' <|> p_char 'b')))
|> resultm.get
|> sm'.format_debug
|> _assert_eq (
("aaabb", "", { line_text = "[aaabb]" |> sm'.string_builder; position = { line = 1i32; col = 8i32 } })
|> sm'.format_debug
)
"[aaabb"
|> parse (between (p_char '[') (p_char ']') (many1_chars (p_char 'a' <|> p_char 'b')))
|> resultm.unwrap_err
|> sm'.format_debug
|> _assert_eq (
backend_switch {
Gleam = fun () =>
"parsing.between / expected closing delimiter / "
++# "{ e = parsing.p_char / unexpected end of input / { c = ]; s = #(\"[aaabb\", 1, 7) }; "
++# "input = [aaabb, #(\"\", 1, 1); rest1 = aaabb, #(\"[\", 1, 2); rest2 = , #(\"[aaabb\", 1, 7) }"
Fsharp = fun () =>
run_target function
| TypeScript _ => fun () =>
"parsing.between / expected closing delimiter / "
++# "{ e = parsing.p_char / unexpected end of input / { c = ]; s = [aaabb,1,7 }; "
++# "input = [aaabb, [aaabb,1,1; rest1 = aaabb, [aaabb,1,2; rest2 = , [aaabb,1,7 }"
| _ => fun () =>
join
"parsing.between / expected closing delimiter / "
++# "{ e = parsing.p_char / unexpected end of input / { c = ]; "
++# "s = struct ([aaabb, 1, 7) }; input = [aaabb, struct ([aaabb, 1, 1); "
++# "rest1 = aaabb, struct ([aaabb, 1, 2); rest2 = , struct ([aaabb, 1, 7) }"
Python = fun () =>
"parsing.between / expected closing delimiter / "
++# "{ e = parsing.p_char / unexpected end of input / { c = ]; s = ([aaabb, 1, 7) }; "
++# "input = [aaabb, ([aaabb, 1, 1); rest1 = aaabb, ([aaabb, 1, 2); rest2 = , ([aaabb, 1, 7) }"
}
)
.py output (Python): { name = __assert_eq; actual = ('aaabb', '', [aaabb], 1, 8); expected = ('aaabb', '', [aaabb], 1, 8) } { name = __assert_eq; actual = parsing.between / expected closing delimiter / { e = parsing.p_char / unexpected end of input / { c = ]; s = ([aaabb, 1, 7) }; input = [aaabb, ([aaabb, 1, 1); rest1 = aaabb, ([aaabb, 1, 2); rest2 = , ([aaabb, 1, 7) }; expected = parsing.between / expected closing delimiter / { e = parsing.p_char / unexpected end of input / { c = ]; s = ([aaabb, 1, 7) }; input = [aaabb, ([aaabb, 1, 1); rest1 = aaabb, ([aaabb, 1, 2); rest2 = , ([aaabb, 1, 7) } } .ts output: { name = __assert_eq; actual = aaabb,,[aaabb],1,8; expected = aaabb,,[aaabb],1,8 } { name = __assert_eq; actual = parsing.between / expected closing delimiter / { e = parsing.p_char / unexpected end of input / { c = ]; s = [aaabb,1,7 }; input = [aaabb, [aaabb,1,1; rest1 = aaabb, [aaabb,1,2; rest2 = , [aaabb,1,7 }; expected = parsing.between / expected closing delimiter / { e = parsing.p_char / unexpected end of input / { c = ]; s = [aaabb,1,7 }; input = [aaabb, [aaabb,1,1; rest1 = aaabb, [aaabb,1,2; rest2 = , [aaabb,1,7 } } .gleam output (Gleam): { name = __assert_eq; actual = #("aaabb", "", "[aaabb]", 1, 8); expected = #("aaabb", "", "[aaabb]", 1, 8) } { name = __assert_eq; actual = parsing.between / expected closing delimiter / { e = parsing.p_char / unexpected end of input / { c = ]; s = #("[aaabb", 1, 7) }; input = [aaabb, #("", 1, 1); rest1 = aaabb, #("[", 1, 2); rest2 = , #("[aaabb", 1, 7) }; expected = parsing.between / expected closing delimiter / { e = parsing.p_char / unexpected end of input / { c = ]; s = #("[aaabb", 1, 7) }; input = [aaabb, #("", 1, 1); rest1 = aaabb, #("[", 1, 2); rest2 = , #("[aaabb", 1, 7) } }
.fsx output: { name = __assert_eq; actual = struct ("aaabb", "", [aaabb], 1, 8); expected = struct ("aaabb", "", [aaabb], 1, 8) } { name = __assert_eq; actual = parsing.between / expected closing delimiter / { e = parsing.p_char / unexpected end of input / { c = ]; s = struct ([aaabb, 1, 7) }; input = [aaabb, struct ([aaabb, 1, 1); rest1 = aaabb, struct ([aaabb, 1, 2); rest2 = , struct ([aaabb, 1, 7) }; expected = parsing.between / expected closing delimiter / { e = parsing.p_char / unexpected end of input / { c = ]; s = struct ([aaabb, 1, 7) }; input = [aaabb, struct ([aaabb, 1, 1); rest1 = aaabb, struct ([aaabb, 1, 2); rest2 = , struct ([aaabb, 1, 7) } }
sep_by¶
In [ ]:
// inl sep_by p sep : parser (list _) = fun input, s =>
inl sep_by forall b. p sep : parser (list b) = fun input, s =>
// let rec 루프 acc input s =
let rec 루프 forall a.
(acc : list b)
(input : string)
(s : parser_state)
: result (list b * string * parser_state) a
=
match p (input, s) with
| Ok (result, rest, s) =>
match sep (rest, s) with
| Ok (_, rest, s) => 루프 (result :: acc) rest s
| Error _ => Ok ((result :: acc) |> listm.rev, rest, s)
| Error _ => Ok (acc |> listm.rev, input, s)
루프 [] input s
span¶
In [ ]:
inl span pred str =
// let rec 루프 i =
let rec 루프 forall t {number; int}. (i : t) : t =
if i >= sm'.length str
then i
elif pred (str |> sm'.index i)
then 루프 (i + 1)
else i
루프 0
spaces1¶
In [ ]:
inl spaces1 () : parser () = fun input, s =>
match input |> span ((=) ' ') with
| 0i32 => Error "parsing.spaces1 / expected at least one space"
| n => Ok ((), input |> sm'.range (am'.Start n) (am'.End eval), s)
spaces¶
In [ ]:
inl spaces () : parser () = fun input, s =>
input
|> span ((=) ' ')
|> fun (n : i32) =>
Ok ((), input |> sm'.range (am'.Start n) (am'.End eval), s)
p_digit¶
In [ ]:
inl p_digit () : parser char = fun input, s =>
match input |> sm'.index 0i32 with
| ('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') as c =>
Ok (c, input |> sm'.range (am'.Start 1i32) (am'.End eval), s)
| c => "parsing.p_digit / unexpected char / " ++# ({ c } |> sm'.format) |> Error
In [ ]:
//// test
///! gleam
///! fsharp
///! cuda
///! typescript
"1 2 3"
|> parse (sep_by (p_digit ()) (spaces1 ()))
|> resultm.get
|> sm'.format_debug
|> _assert_eq (
(['1'; '2'; '3'], "", { line_text = "" |> sm'.string_builder; position = { col = 1i32; line = 1i32 } })
|> sm'.format_debug
)
.py output (Python): { name = __assert_eq; actual = (UH0_1(v0='1', v1=UH0_1(v0='2', v1=UH0_1(v0='3', v1=UH0_0()))), '', , 1, 1); expected = (UH0_1(v0='1', v1=UH0_1(v0='2', v1=UH0_1(v0='3', v1=UH0_0()))), '', , 1, 1) } .ts output: { name = __assert_eq; actual = UH0_1 (1, UH0_1 (2, UH0_1 (3, UH0_0))),,,1,1; expected = UH0_1 (1, UH0_1 (2, UH0_1 (3, UH0_0))),,,1,1 } .gleam output (Gleam): { name = __assert_eq; actual = #(Uh0i1("1", Uh0i1("2", Uh0i1("3", Uh0i0))), "", "", 1, 1); expected = #(Uh0i1("1", Uh0i1("2", Uh0i1("3", Uh0i0))), "", "", 1, 1) }
.fsx output: { name = __assert_eq; actual = struct (UH0_1 ('1', UH0_1 ('2', UH0_1 ('3', UH0_0))), "", , 1, 1); expected = struct (UH0_1 ('1', UH0_1 ('2', UH0_1 ('3', UH0_0))), "", , 1, 1) }
In [ ]:
//// test
///! gleam
///! fsharp
///! cuda
///! typescript
////! python // __assert_eq / actual: (UH0_1 ("1", UH0_0), 'a 2', <fable_modules.fable_library.system_text.StringBuilder object at 0x0000000001A10500>, 1, 1) / expected: (UH0_1 ("1", UH0_0), 'a 2', <fable_modules.fable_library.system_text.StringBuilder object at 0x0000000001A10590>, 1, 1)
"1 a 2"
|> parse (sep_by (p_digit ()) (spaces1 ()))
|> resultm.get
|> sm'.format_debug
|> _assert_eq (
(['1'], "a 2", { line_text = "" |> sm'.string_builder; position = { col = 1i32; line = 1i32 } })
|> sm'.format_debug
)
.py output (Python): { name = __assert_eq; actual = (UH0_1(v0='1', v1=UH0_0()), 'a 2', , 1, 1); expected = (UH0_1(v0='1', v1=UH0_0()), 'a 2', , 1, 1) } .ts output: { name = __assert_eq; actual = UH0_1 (1, UH0_0),a 2,,1,1; expected = UH0_1 (1, UH0_0),a 2,,1,1 } .gleam output (Gleam): { name = __assert_eq; actual = #(Uh0i1("1", Uh0i0), "a 2", "", 1, 1); expected = #(Uh0i1("1", Uh0i0), "a 2", "", 1, 1) }
.fsx output: { name = __assert_eq; actual = struct (UH0_1 ('1', UH0_0), "a 2", , 1, 1); expected = struct (UH0_1 ('1', UH0_0), "a 2", , 1, 1) }
opt¶
In [ ]:
inl opt p : parser (option _) = fun input, s =>
match p (input, s) with
| Ok (result, rest, s) => Ok (Some result, rest, s)
| Error _ => Ok (None, input, s)
rest_of_line¶
In [ ]:
inl rest_of_line () : parser string = fun input, s =>
inl i : i32 = input |> span ((<>) '\n')
inl result = input |> sm'.range (am'.Start i) (am'.End eval)
Ok (result, result, s)
eof¶
In [ ]:
inl eof () : parser () = fun input, s =>
if sm'.length input = 0i32
then Ok ((), input, s)
else "parsing.eof / expected end of input / " ++# ({ input } |> sm'.format) |> Error