Stream: helpdesk (published)

Topic: ✔ Macro to generate DSL parser code


view this post on Zulip Jakob Nybo Nissen (Oct 29 2025 at 18:20):

You can programmatically generate the regex. A similar option is to use Automa.jl to do this, which is a pure Julia regex engine

view this post on Zulip Viktor G. (Oct 29 2025 at 20:49):

Thanks, I did this based on this examle:
https://github.com/wdebeaum/PEG.jl/blob/master/test/calculator.jl

using PEG

@rule Word = r"\w+\*" |> w-> :(occursin(Regex("\\b$($(w[1:end-1]))"), str)), # prefix*
    r"\w+" |> w-> :(occursin(Regex("\\b$($(w))\\b"), str)), # word
    r"\("p & Add & r"\)"p |> x->x[2] # (a)
@rule Neg = r"!" & Word |> w->:(!$(w[2])) , Word # !a
@rule Mul = Neg & (r"[/&]"p & Neg)[*] |> do_op # a&b
@rule Add = Mul & (r"[+-|]"p & Mul)[*] |> do_op # a|b

function do_op(x)
    v, op_v_pairs = x
    expr = :( $(v) )
    for (op, v2) in op_v_pairs
        sym_op = Symbol(op)
        expr = :( $(sym_op)($(expr), $(v2)) )
    end
    return expr
end

pattern1 = "Julia&lang*&!Roberts"
# @info parse_whole(Add, pattern1)
@generated compiled_pattern1(str) = parse_whole(Add, pattern1)

compiled_pattern1("Julia Roberts") # == false
compiled_pattern1("Julia language") # == true

view this post on Zulip Viktor G. (Oct 29 2025 at 23:07):

Also added macro to skip function definitions:

@generated function check_str_compiled(str, ::Val{pattern}) where pattern
    parse_whole(Add, String(pattern))
end

macro check_str(str, pattern)
    :(check_str_compiled($str, Val(Symbol($pattern))))
end

@check_str("Julia language", "Julia&lang*&!Roberts") == true
@check_str("Julia Roberts", "Julia&lang*&!Roberts") == false

view this post on Zulip Notification Bot (Oct 29 2025 at 23:19):

Viktor G. has marked this topic as resolved.


Last updated: Nov 07 2025 at 04:42 UTC