Skip to content

Instantly share code, notes, and snippets.

@d11wtq
Created November 4, 2011 07:31
Show Gist options
  • Save d11wtq/1338851 to your computer and use it in GitHub Desktop.
Save d11wtq/1338851 to your computer and use it in GitHub Desktop.
require "parslet"
class MiniP < Parslet::Parser
rule(:wsp) { match("\\s").repeat(1) }
rule(:wsp?) { wsp.maybe }
rule(:t_int) { match("[0-9]").repeat(1).as(:int) }
# this is causing Stack Level Too Deep
rule(:sum) { expr.as(:left) >> wsp? >> str("+") >> wsp? >> expr.as(:right) }
# but this is fine
rule(:arg_list) { expr >> wsp? >> (str(",") >> wsp? >> expr).repeat }
rule(:add_call) { str("add") >> wsp? >> str("(") >> wsp? >> arg_list.as(:args) >> wsp? >> str(")") }
rule(:expr) { sum.as(:sum) | add_call.as(:add_call) | t_int }
root(:expr)
end
class MiniT < Parslet::Transform
rule(:int => simple(:int)) { |dict| Integer(dict[:int]) }
rule(:args => sequence(:args)) { |dict| dict[:args] }
rule(:sum => { :left => simple(:left), :right => simple(:right) }) { |dict| dict[:left] + dict[:right] }
rule(:add_call => subtree(:args)) { |dict| dict[:args].reduce(&:+) }
end
expr = "add(add(4, 5), add(1, 1 + add(0, 1)))"
p MiniP.new.parse(expr)
p MiniT.new.apply(MiniP.new.parse(expr))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment