[ANN] PikaMacros.jl: Declarative grammars via PikaParser.jl

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 :slight_smile:.

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.

The repo is here on GitHub.

Cheers all!

very cool :slight_smile:
not sure i can provide much feedback as i am not an expert in this topic, but from what ive seen it looks like it could be useful for people, so great job! earned yourself a star too if that helps :grin:

Thanks! I’m not much of an expert in this topic either, alas :smiley: just happened to need to write a parser whilst I was fooling around with metaprogramming!