首页 > 解决方案 > 如何让 Automa.jl 接受来自标准输入的输入?

问题描述

我有一些使用Automa.jl解析字符串的代码。我相信它只是从左到右穿过字符串。我的输入文件只有一行,非常大,所以我想避免将它全部加载到内存中。因此,我希望我的代码能够处理来自标准输入的(巨大的)字符串,但我不知道该怎么做。这是我的代码(由 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

你怎么能改变它以便 parsestring 接受来自标准输入的字符串?

标签: julia

解决方案


我的输入文件只有一行,非常大,所以我想避免将它全部加载到内存中。

你可以映射它

using MMap
Mmap.mmap(file)

并将结果传递Vector{UInt8}parsestring.

你怎么能改变它以便 parsestring 接受来自标准输入的字符串?

stdin是一个流,所以你需要parsestring能够接受一个IO对象。


推荐阅读