Mercurial > lbo > hg > juliaplay
changeset 33:2d033830c26e
Implement struct-specific parser
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Sun, 19 Mar 2023 20:20:13 +0100 |
parents | 3d916aa02d00 |
children | a36e3e66ae3e |
files | julia/parallel/ParallelProcessing/src/ParallelProcessing.jl julia/parallel/ParallelProcessing/src/json.jl julia/parallel/ParallelProcessing/src/jsonparser.jl |
diffstat | 3 files changed, 72 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/julia/parallel/ParallelProcessing/src/ParallelProcessing.jl Sun Mar 19 20:04:34 2023 +0100 +++ b/julia/parallel/ParallelProcessing/src/ParallelProcessing.jl Sun Mar 19 20:20:13 2023 +0100 @@ -1,5 +1,5 @@ module ParallelProcessing +include("jsonparser.jl") include("json.jl") -include("jsonparser.jl") end # module ParallelProcessing
--- a/julia/parallel/ParallelProcessing/src/json.jl Sun Mar 19 20:04:34 2023 +0100 +++ b/julia/parallel/ParallelProcessing/src/json.jl Sun Mar 19 20:20:13 2023 +0100 @@ -7,6 +7,47 @@ kind::Int end +"""Example for a method that can be derived straight from a struct definition and parses just a struct + from a JSON object.""" +function take_struct!(t::Type{Details}, jp::JP)::Union{Nothing,Details} + expect!(jp, '{') || return nothing + + level::Union{Nothing,String} = nothing + kind::Union{Nothing, Int} = nothing + while true + key = take_str!(jp) + if isnothing(key) + break + end + + expect!(jp, ':') || error("malformed object - expected ':'") + + # Custom code! + if key == "level" + level = take_str!(jp) + elseif key == "kind" + kind = take_num!(jp) + else + # Ignore unknown keys + take_val!(jp) + end + + if expect!(jp, ',') + continue + else + break + end + end + + if isnothing(level) || isnothing(kind) + error("Elements missing from object: $level, $kind") + end + + expect!(jp, '}') || error("unclosed Details object") + + Details(level, kind) +end + struct SimpleEntry s::String a::Int
--- a/julia/parallel/ParallelProcessing/src/jsonparser.jl Sun Mar 19 20:04:34 2023 +0100 +++ b/julia/parallel/ParallelProcessing/src/jsonparser.jl Sun Mar 19 20:20:13 2023 +0100 @@ -31,6 +31,22 @@ end end +function take_num!(jp::JP)::Union{Nothing,Float64,Int} + pred(c) = isdigit(c) || (c == '-') || (c == '.') # todo: exponential numbers + span = takewhile!(jp, pred) + if isnothing(span) + nothing + else + a, b = span + s = (@view jp.s[a:b]) + if contains(s, '.') + parse(Float64, s) + else + parse(Int, s) + end + end +end + function take_bool!(jp::JP)::Union{Nothing,Bool} if expect_prefix!(jp, "true") true @@ -41,38 +57,38 @@ end end -function take_dict!(jp::JP)::Union{Nothing,Dict{String,Any}} +function take_object!(jp::JP)::Union{Nothing,Dict{String,Any}} expect!(jp, '{') || return nothing d = Dict{String,Any}() while true key = take_str!(jp) if isnothing(key) - # Empty dict + # Empty object break end - expect!(jp, ':') || error("malformatted dict - expecting ':'") + expect!(jp, ':') || error("malformatted object - expecting ':'") - val = take_obj!(jp) + val = take_val!(jp) d[key] = val if expect!(jp, ',') continue else - # End of dict + # End of object break end end - expect!(jp, '}') || error("Unclosed dict - '}' missing") + expect!(jp, '}') || error("Unclosed object - '}' missing") d end function take_str!(jp::JP)::Union{Nothing,String} expect!(jp, '"') || return nothing - span = takewhile!(jp, (!=)('"')) + span = takewhile!(jp, (!=)('"'), false) if isnothing(span) error("unclosed string at $(jp.pos)") end @@ -87,7 +103,7 @@ l = Any[] while true - o = take_obj!(jp) + o = take_val!(jp) if isnothing(o) break else @@ -105,8 +121,9 @@ l end -function take_obj!(jp::JP)::Union{Nothing,Any} - d = take_dict!(jp) +"""value is anything - object/list/number/boolean/string""" +function take_val!(jp::JP)::Union{Nothing,Any} + d = take_object!(jp) if !isnothing(d) return d end @@ -129,9 +146,10 @@ nothing end -function parse_object(s::AbstractString) +"""Parse a json value..""" +function parse_value(s::AbstractString) jp = JP(s) - take_obj!(jp) + take_val!(jp) end function takewhile!(jp::JP, pred::Function, stripws=true)::Union{Nothing,Tuple{Int,Int}}