I have some code which parses a string using Automa. I believe it simply travels through the string from left to right. I would like to make it work on a string coming from stdin but I am not sure how to do it. Here is my code (written by Jakob Nissen):
import Automa
import Automa.RegExp: @re_str
const re = Automa.RegExp
machine = (function ()
# Primitives
start = re"\["
stop = re"\]"
sep = re"," * re.opt(re.space())
number = re"[0-9]+"
numelem = number * (sep | stop)
elems = re"[^\[]+" * re.rep(start | stop | sep | numelem)
start.actions[:enter] = [:start]
stop.actions[:enter] = [:stop]
number.actions[:enter] = [:mark]
number.actions[:exit] = [:number]
return Automa.compile(elems)
end)()
actions = Dict(
:start => quote
# level > 1 && error("X")
level == 1 && (inner = UInt32[])
level += 1
end,
:stop => quote
# level == 0 && error("")
level == 2 && push!(outer, inner)
level -= 1
level == 0 && (done = true)
end,
:mark => :(mark = p),
:number => quote
n = UInt32(0)
@inbounds for i in mark:p-1
n = n * 10 + UInt32(data[i] - 0x30)
end
push!(inner, n)
end
)
context = Automa.CodeGenContext()
@eval function parsestring(data::Union{String,Vector{UInt8}})
mark = 0
level = 0
done = false
inner = UInt32[]
outer = Vector{UInt32}[]
$(Automa.generate_init_code(context, machine))
p_end = p_eof = lastindex(data)
$(Automa.generate_exec_code(context, machine, actions))
if (cs != 0) & (!done)
error("failed to parse on byte ", p)
end
return outer
end
How can you change this so that parsestring accepts a string coming from stdin?