Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

confused by tagged repetitions #13

Closed
blowback opened this Issue · 2 comments

2 participants

@blowback

I'm confused by the combo of tags and repetition operators! For example, this grammar:

grammar G
rule foo
    ('A' opt:bar? 'Z') <Foo>
end

rule bar
    ('B')  <Bar>
end
end

Matching against the string "AZ", I'd expect match to have methods from module Foo, which it does.

Matching against the string "ABZ", I'd expect match to have methods from module Foo (yep), and 'match.opt' to have methods from module Bar, but opt hasn't been extended by Bar.

If I change the middle clause of rule foo to instead read (opt:bar)? (ie, add parentheses) then it works as expected.

So, I suspect precedence, but I'm at a loss to explain why that should determine whether module Bar is included or not. Any pointers?

(citrus 2.3.1 ruby 1.9.2)

@mjackson
Owner

This is definitely a precedence problem, as you've already noticed. The problem is that the repeat operator (the ?) binds tighter than the label (the opt). This means that bar will indeed be extended with the methods of Bar, but calling opt won't give you the same match as you get when you call bar.

Instead, calling opt will give you the result of the repeat operator match, which in this case is an object that wraps zero or one bar matches. The following example should help to clear things up.

module Foo
  def value
    'foo'
  end
end

module Bar
  def value
    'bar'
  end
end

Citrus.eval(<<CITRUS)
grammar G
  rule foo
    ('A' opt:bar? 'Z') <Foo>
  end

  rule bar
    'B' <Bar>
  end
end
CITRUS

match = G.parse 'ABZ'

match.value
# => "foo"
match.bar.value
# => "bar"
puts match.opt.bar.value
# => "bar"

Now, just because this is the way the library currently behaves doesn't mean that it's the best way. ;) I'm open to suggestions for change if you have them.

@blowback

Thanks, that makes sense. I like your approach of strict precedence that applies to everything, it's logical and less wishy-washy than other cheaper brand PEGs that I'd become accustomed to ;)

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.