In general, this is somewhat similar to paren-balancing task. 
https://github.com/kschiess/parslet/blob/master/example/parens.rb

That might help you. Although wait, I guess that particular example 
doesn't allow your parens to have any content, heh.

Although what you are doing may be even simpler than a paren balancing 
task with content -- What do you want to happen to your nested blocks?  
They don't need to be parsed out seperately, they are still gobbled up 
in just one string, the top level block structure?

But I think that example should give you some hints maybe, or the more 
complicated one that actually lets the parens have content, here: 
https://github.com/kschiess/parslet/blob/master/example/minilisp.rb








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>

Reply via email to