Ie, something like this maybe (just typing it into the email client,
dont' know if it even compiles, let alone works, but may give you some
ideas).
rule :block do
str('{') << content.maybe << block.maybe << content.maybe << str('}'
end
rule :content do
match['^{}].repeat
end
The trick I think might work is the recursive call to block that will
allow a (balanced) block to be inside a block, but otherwise we dont'
allow '{' or '}'. Except I actually have no idea if this will actually
work, heh, but some ideas to work with.
On 5/18/2011 11:37 AM, Joe Hellerstein wrote:
> 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>