Có thể sử dụng Automa.jl để xây dựng DFA và duyệt ngẫu nhiên nó. Automa sử dụng một cú pháp đơn giản hơn PCRE, do đó, ngôn ngữ bạn có thể mô tả bằng nó thực sự nên thường xuyên.
Tôi nhanh chóng tập hợp các mục sau, chủ yếu dựa vào mã trong dot.jl
:
julia> function rand_re(machine::Automa.Machine)
out = IOBuffer()
node = machine.start
while true
if node.state ∈ machine.final_states
(rand() ≤ 1 / (length(node.edges) + 1)) && break
end
edge, node = rand(node.edges)
label = rand(collect(edge.labels))
print(out, Char(label))
end
return String(take!(out))
end
rand_re (generic function with 1 method)
julia> rand_re(Automa.compile(re"a[0-9][ab]+"))
"a6bbb"
julia> rand_re(Automa.compile(re"a[0-9][ab]+"))
"a9b"
julia> rand_re(Automa.compile(re"a[0-9][ab]+"))
"a3aa"
julia> rand_re(Automa.compile(re"a[0-9][ab]+"))
"a1a"
julia> rand_re(Automa.compile(re"a[0-9][ab]+"))
"a5ba"
Thông báo trước là Automa sử dụng các bộ được mã hóa byte cho các nhãn cạnh, vì vậy cần cẩn thận hơn khi tôi chỉ viết Char(label)
.
Vì các trạng thái cuối cùng vẫn có thể có các cạnh đi, tôi đã chọn xử lý dừng và mỗi cạnh với xác suất đồng nhất. Tôi nghĩ rằng điều này có thể sẽ có tác động rằng các thuật ngữ có khả năng vô hạn sẽ rất ngắn hoặc rất dài; google "Bộ lấy mẫu Boltzmann" để biết cách giải quyết điều đó (không bị nhầm lẫn với lấy mẫu từ bản phân phối Boltzmann!), nhưng giải pháp này khá liên quan đến toán học.