Firstly - great package, thank you for all your hard work!
I have been wrapping the PikaParser.jl workflow in a few macros, and wanted to float them for your consideration.
The two macros are in the gist here -- @pika_grammar produces a callable function which parses the input, and @pika_evaluate provides syntactic sugar for fold-function definitions.
I think an example is best - a simple calculator with whitespace (mind I don't write many PEG grammars, so you will probably find a better way of doing this!)
The grammar is defined with this macro like so:
calc_grammar = @pika_grammar :top begin
:ws => many(satisfy(isspace)),
:digit => satisfy(isdigit),
:number => some(:digit),
:plus => seq(:expr, :ws, token('+'), :ws, :expr, :ws),
:minus => seq(:expr, :ws, token('-'), :ws, :expr, :ws),
:times => seq(:expr, :ws, token('*'), :ws, :expr, :ws),
:divby => seq(:expr, :ws, token('/'), :ws, :expr, :ws),
:paren => seq(:ws, token('('), :ws, :expr, :ws, token(')'), :ws),
:expr => first(:paren, :times, :divby, :plus, :minus, :number),
:top => seq(:expr)
end
(Note that the @pika_grammar macro traverses the syntax tree, and replaces PikaParser.jl library symbols with their qualified names, e.g. seq => PikaParser.seq).
Now we write the evaluator with some additional output:
calc_eval = @pika_evaluate :top m v begin
:number => parse(Int, m.view)
:plus => begin
println("Parsing plus: $(m.view) => $(v[1]) + $(v[5])")
v[1] + v[5]
end
:minus => begin
println("Parsing minus: $(m.view) => $(v[1]) - $(v[5])")
v[1] - v[5]
end
:times => begin
println("Parsing times: $(m.view) => $(v[1]) * $(v[5])")
v[1] * v[5]
end
:divby => begin
println("Parsing divby: $(m.view) => $(v[1]) / $(v[5])")
v[1] / v[5]
end
:expr => v[1]
:paren => v[4]
:top => begin
println("Parsing top: $(m.view) => $(v[1])")
v[1]
end
end
Finally, we parse according to the grammar and evaluate:
julia> calc_grammar("12 + ( 34* 56)") |> calc_eval
Parsing times: 34* 56 => 34 * 56
Parsing plus: 12 + ( 34* 56) => 12 + 1904
Parsing top: 12 + ( 34* 56) => 1916
1916
Please let me know if I can be of any help - whether there are additional aspects to consider, or whether I should open a pull request.
And once again, thanks for the great parsing library!
Firstly - great package, thank you for all your hard work!
I have been wrapping the PikaParser.jl workflow in a few macros, and wanted to float them for your consideration.
The two macros are in the gist here --
@pika_grammarproduces a callable function which parses the input, and@pika_evaluateprovides syntactic sugar for fold-function definitions.I think an example is best - a simple calculator with whitespace (mind I don't write many PEG grammars, so you will probably find a better way of doing this!)
The grammar is defined with this macro like so:
(Note that the
@pika_grammarmacro traverses the syntax tree, and replaces PikaParser.jl library symbols with their qualified names, e.g.seq => PikaParser.seq).Now we write the evaluator with some additional output:
Finally, we parse according to the grammar and evaluate:
Please let me know if I can be of any help - whether there are additional aspects to consider, or whether I should open a pull request.
And once again, thanks for the great parsing library!