I don't follow how you felt it would work that way...
If you unroll your logic you get
*str('a').as <http://rule1.as/>(:a).maybe >> ( str('a').present? >> str('b')
.as <http://rule2.as/>(:b1) ) | str('b').as <http://rule2.as/>(:b2)
*
which says "consume an 'a' if there is one" then "if there is another 'a'
next, only match 'b'" or "read in a 'b'"
*str('a').present? >> **str('b') * will never match anything.
so.. it sounds like you wanted to say..
Match "a" if there is one
If I matched "a" then matching a 'b' should mark it as 'b1'
otherwise matching a 'b' should mark it as 'b2'
'*If I matched "a"*' would be looking backwards not forwards so 'present?'
isn't going to work.
Your goal however is the same as saying:
"Either match "ab" (marking the b as 'b1')
Or match "b" (marking the b as "b2")
Written like this... it becomes
( str('a') >> str('b').as(:b1) ) | ( str('b').as(:b2) )
The 'a' isn't optional. It's the existence of the 'a' that makes the parser
take that branch.
Does this make clarify anything?
---
"No man is an island... except Philip"
On Fri, Jun 28, 2013 at 5:17 PM, Kaspar Schiess <[email protected]>wrote:
> Hei Li,
>
> When parsing the string 'ab', the rule4 use of rule1 will consume 'a',
> leaving 'b' in the input string. Then it will try to match rule1 (for
> rule1.present?) again - but the input string at that point just contains
> 'b', so :b2 matches and is consumed, yielding a successful match.
>
> > So 'present?' can not span rules? In my real application, the problem is
> > more complicated, so I can not just merge 'rule3' and 'rule4'.
> #present? protects subsequent matches in the same sequence from matching
> unless the atom given to present is available at that point. So no, it
> doesn't somehow span multiple rules, it has very local action. You will
> need to formulate this differently.
>
> If you post a piece of your parser, maybe the list will help you
> reformulate what you want so that present? works?
>
> cheers!
> kaspar
>
>
>
>