Hi all,
This is a small package meant to provide a front-end syntax to the excellent PikaParser.jl package.
This package can be used to parse arbitrary strings, or for implementing DSLs via str and cmd macros.
For an example, here is a simple arithmetic evaluator:
syn = @syntax :top begin
:ws => many(satisfy(isspace))
:number => some(:digit => satisfy(isdigit))
:plus => seq(:pexpr, :ws, token('+'), :ws, :pexpr, :ws)
:minus => seq(:pexpr, :ws, token('-'), :ws, :pexpr, :ws)
:times => seq(:pexpr, :ws, token('*'), :ws, :pexpr, :ws)
:divby => seq(:pexpr, :ws, token('/'), :ws, :pexpr, :ws)
:paren => seq(token('('), :ws, :expr, :ws, token(')'), :ws)
:expr => first(:times, :divby, :plus, :minus, :number)
:pexpr => first(:paren, :expr)
:top => seq(:ws, :pexpr)
end
sem = @semantics :top m v begin
:number => parse(Int, m.view)
:expr => v[1]
:plus => v[1] + v[5]
:minus => v[1] - v[5]
:times => v[1] * v[5]
:divby => v[1] / v[5]
:paren => v[3]
:expr => v[1]
:pexpr => v[1]
:top => v[2]
end
calc(x) = x |> syn |> sem
calc("3 + 2 + 8") # => 13
calc("3 * (2 + 16)") # => 54
calc("3 + 5 * (2 + 16)") # => 93
A neat trick is that the PikaParser.jl grammar is built at macro-expansion time, if possible. This should allow for aggressive optimisation during precompilation, if I understand the Julia internals right.
No AI was harmed in the making of this package
.
Feel free to raise issues and PRs! I’ll do the best I can to solve them, but life is a bit hectic at the moment.
Cheers all!