This is probably an elementary question, so forgive me.
I'm writing a little DSL and would like it to be able to contain embedded Ruby
blocks (delimited by curly braces or do/end). During parsing I'd like to just
gobble up the text of the block and stuff it into a single node in the AST.
Of course there may be nested blocks inside the Ruby. The nesting examples on
the website seem to explicitly parse any matching delimiters. But I don't want
to parse the Ruby here, I just want to gobble it up. However, catching the
Ruby as
str('{') >> any.repeat(1) >> str('}')
causes parsing to fail since the rightmost curly brace gets captured by the
any.repeat. I include an example below and output.
Any suggestions?
Thanks.
Joe
require 'rubygems'
require 'parslet'
class Mini < Parslet::Parser
rule(:lbrace) { str('{') >> space? }
rule(:rbrace) { str('}') >> space? }
rule(:word) { match['a-z'].repeat(1) >> space? }
rule(:space) { match('\s').repeat(1) }
rule(:space?) { space.maybe }
rule(:block) { lbrace >> any.repeat(1) >> rbrace }
rule(:stmt) { (block.as(:block) | word).repeat }
root :stmt
end
def parse(str)
mini = Mini.new
print "Parsing #{str}: "
p mini.parse(str)
rescue Parslet::ParseFailed => error
puts error, mini.root.error_tree
end
parse "joe is here {hi}"
(joeh@manila) 1351 > ruby lilparse.rb
Parsing joe is here {hi}: Don't know what to do with {hi} at line 1 char 13.
`- Expected one of [block:BLOCK, WORD]. at line 1 char 13.
|- Failed to match sequence (LBRACE .{1, }) at line 1 char 17.
| `- Failed to match sequence ('}' SPACE?) at line 1 char 17.
| `- Premature end of input at line 1 char 17.
`- Failed to match sequence ([a-z]{1, } SPACE?) at line 1 char 13.
`- Expected at least 1 of [a-z] at line 1 char 13.
`- Failed to match [a-z] at line 1 char 13.
(joeh@manila) 1352 >