Sha256: 2204cd71b1003b725720737713d8ad9620a9ad58811c0b444d873ca3493475f8
Contents?: true
Size: 1.55 KB
Versions: 12
Compression:
Stored size: 1.55 KB
Contents
grammar IndentedBlocks rule top # Initialise the indent stack with a sentinel: &{|s| @indents = [-1] } foo:('foo'?) nested_blocks { def inspect nested_blocks.inspect end } end rule nested_blocks ( # Do not try to extract this semantic predicate into a new rule. # It will be memo-ized incorrectly because @indents.last will change. !{|s| # Peek at the following indentation: save = index; i = _nt_indentation; index = save # We're closing if the indentation is less or the same as our enclosing block's: closing = i.text_value.length <= @indents.last } block )* { def inspect elements.map{|e| e.block.inspect}*"\n" end } end rule block indented_line # The block's opening line &{|s| # Push the indent level to the stack level = s[0].indentation.text_value.length @indents << level true } nested_blocks # Parse any nested blocks &{|s| # Pop the indent stack # Note that under no circumstances should "nested_blocks" fail, or the stack will be mis-aligned @indents.pop true } { def inspect indented_line.inspect + (nested_blocks.elements.size > 0 ? ( "\n{\n" + nested_blocks.elements.map { |content| content.block.inspect+"\n" }*'' + "}" ) : "") end } end rule indented_line indentation text:((!"\n" .)*) "\n" { def inspect text.text_value end } end rule indentation ' '* end end
Version data entries
12 entries across 12 versions & 2 rubygems