so why isn't this just something like

rule(:line) { statement.maybe? >> line_comment.maybe? >> eol }
rule(:line_comment) { str("!") >> ( eol.absent? >> any).repeat }

If you need to treat comments on the same line differently to on a
different line, then yes I would have another rule.

---
"No man is an island... except Philip"


On Sat, Jun 29, 2013 at 3:47 PM, Li Dong <[email protected]> wrote:

> Hi Nigel,
>
> Thanks for replying!
>
> The real context of the problem is as following:
>
> In Fortran code, we write comment like:
>
> >   ! This is a comment line.
> >       use foo     ! This is a comment following a use statement.
>
> then there are two scenarios: 1. A whole-line comment; 2. A inline
> comment. And I would like to reformat (or re-indent) the code into:
>
> >    ! This is a comment line.
> >    use foo ! This is a comment following a use statement.
>
> so I need to process the two kinds of comment differently, for the first
> one, it should follow the current ind entation, for the second one, it
> should follow the previous statement with one space between them.
>
> Based on Kaspar's explanation, the lookahead can't span rules, so this
> can't be achieved by using lookahead to check what scenario is (I have a
> lot of rules).
>
> My potential solution would be that write two rules for the different
> comment scenario (currently they are parsed with the same rule).
>
> Cheers,
>
> Li
>
> 在 2013-6-29,下午1:24,Nigel Thorne <[email protected]> 写道:
>
> 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(: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
>>
>>
>>
>>
>
>

Reply via email to