cloudRoutine/Toml.FSharp

Error when parsing simple table

Opened this issue · 3 comments

Issue
Parser fails on the following:

let test = TomlFSharp.Read.readTomlString """
[package]

author = ["Test"]
"""

with this error

> 
System.AggregateException: One or more errors occurred. ---> System.Exception: Error in Ln: 3 Col: 10
author = 
         ^
Note: The error occurred at the end of the input stream.
The char `�` with int value: 65535 at Ln 3 Col 10, was unexpected in a parse
for a TOML value

   at Microsoft.FSharp.Core.Operators.FailWith[T](String message)
>    at Microsoft.FSharp.Collections.ArrayModule.Parallel.Map@1089-3.Invoke(Int32 obj)
   at System.Threading.Tasks.Parallel.<>c__DisplayClass17_0`1.<ForWorker>b__1()
   at System.Threading.Tasks.Task.InnerInvoke()
   at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)
   at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object )
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.Wait()
   at System.Threading.Tasks.Parallel.ForWorker[TLocal](Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Func`4 bodyWithLocal, Func`1 localInit, Action`1 localFinally)
   at System.Threading.Tasks.Parallel.For(Int32 fromInclusive, Int32 toExclusive, Action`1 body)
   at Microsoft.FSharp.Collections.ArrayModule.Parallel.Map[T,TResult](FSharpFunc`2 mapping, T[] array)
   at FParsec.Primitives.op_BarGreaterGreater@143.Invoke(CharStream`1 stream)
   at FParsec.Primitives.op_DotGreaterGreaterDot@104.Invoke(CharStream`1 stream)
   at FParsec.Primitives.op_BarGreaterGreater@143.Invoke(CharStream`1 stream)
   at FParsec.CharParsers.applyParser[Result,UserState](FSharpFunc`2 parser, CharStream`1 stream)
   at FParsec.CharParsers.runParserOnString@67.Invoke(CharStream`1 stream)
   at FParsec.CharStream.ParseString[T,TUserState](String chars, Int32 index, Int32 length, FSharpFunc`2 parser, TUserState userState, String streamName)
   at FParsec.CharParsers.runParserOnString[a,u](FSharpFunc`2 parser, u ustate, String streamName, String chars)
   at FSI_0002.TomlFSharp.Read.readTomlString(String text) in C:\Users\nat\Projects\toml-fs\src\Toml.FSharp\Parsers.fs:line 530
   at <StartupCode$FSI_0003>.$FSI_0003.main@() in C:\Users\nat\Projects\toml-fs\src\Toml.FSharp\Script.fsx:line 335
---> (Inner Exception #0) System.Exception: Error in Ln: 3 Col: 10
author = 
         ^
Note: The error occurred at the end of the input stream.
The char `�` with int value: 65535 at Ln 3 Col 10, was unexpected in a parse
for a TOML value

   at Microsoft.FSharp.Core.Operators.FailWith[T](String message)
   at Microsoft.FSharp.Collections.ArrayModule.Parallel.Map@1089-3.Invoke(Int32 obj)
   at System.Threading.Tasks.Parallel.<>c__DisplayClass17_0`1.<ForWorker>b__1()
   at System.Threading.Tasks.Task.InnerInvoke()
   at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)
   at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object )<---

Stopped due to error

Steps to reproduce
Send the required dependencies to FSI (the first couple of lines at the top of the file), and then send the snippet above to FSI.

The same error will occur if the text is saved in a file and readFromTomlFile is used

^^ Just realized I forgot to say that I was running this in Script.fsx.

Well I've noticed

[package]
author = [ 10, 10 ]

works

author = [ 10 ]

fails

author = [  ]

fails

The best way to diagnose these issues is to break it down into component parts

let prun psr str = run psr str |> printfn "%A"
prun pArray_toml  "[ 10 ]"
;;
> Success: [Float 10.0]
val it : unit = ()
prun toml_item "a = []"
;;
>Success: ("a", Array [])
val it : unit = ()

You can get all the threading stuff out of the stack trace by changing

    let parse_toml_table =
       (toml_section .>>. (section_splitter |>> fun ls ->
            Array.ofList ls |> Array.Parallel.map parse_block))
        |>> construct_toml


    let parse_to_print = 
        toml_section .>>. (section_splitter |>> fun ls ->
            Array.ofList ls |> Array.Parallel.map parse_block)
        |>> sprint_parse_array 

// Array.Parallel.map -> Array.map

    let parse_toml_table =
       (toml_section .>>. (section_splitter |>> fun ls ->
            Array.ofList ls |> Array.map parse_block))
        |>> construct_toml


    let parse_to_print = 
        toml_section .>>. (section_splitter |>> fun ls ->
            Array.ofList ls |> Array.map parse_block)
        |>> sprint_parse_array 

By adding a print statement in

    let parse_toml_table =
       (toml_section .>>. (section_splitter |>> fun ls ->
            ls |> List.iter (fun (a,b)-> printfn "%A\n%A" a b )
            Array.ofList ls |> Array.map parse_block))
        |>> construct_toml

while running on

let test = TomlFSharp.Read.readTomlString """
[package]
a = [ 10, 10 ]
b = [ 10 ]
"""

It printed

"[package]"
"
a = [ 10, 10 ]
b = "

which explains why there'd be an EOF error there, the section splitter is prematurely truncating the section.

@NatElkins if you want to take a stab at fixing this I've gotten you most of the way there ;P
I've got a bunch of other stuff to work on so I probably won't get back to this for a while