Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Parse::RecDescent - Any Way to do a Negation?

by Incognito (Pilgrim)
on Mar 14, 2002 at 01:54 UTC ( #151578=perlquestion: print w/replies, xml ) Need Help??
Incognito has asked for the wisdom of the Perl Monks concerning the following question:

I have a production which has some negative logic in it... Basically, how do we define XXX so that it is YYY but not 'a' or 'b' or ZZZ, OR 'something else'? I've provided some pseudo-code for this, but can't get further than what's below:
XXX: YYY # BUT NOT 'a' | 'this string' | ZZZ | 'something' 'else' YYY: 'some string' ZZZ: 'ww' | 'xx' | 'yy' | 'zz'
I'm wondering if the gods of Parse::RecDescent know how I can implement this....

Replies are listed 'Best First'.
Re: Parse::RecDescent - Any Way to do a Negation?
by ajwans (Scribe) on Mar 14, 2002 at 02:52 UTC
    Masem is correct, use the reject keyword.

    XXX: YYY | 'something' 'else' | 'a' <reject> | 'this string' <reject> | ZZZ <reject> YYY: 'some string' ZZZ: 'ww' | 'xx' | 'yy' | 'zz'
    This will cause the parse to fail for this branch, be careful that your grammar is not set up so that there are alternate paths to parse the string and your
    $parser->start ($string);
    will fail.

    "Don't you hate it when people quote themselves?" - me
      I'll give it a try, but we're actually trying to do this:
      YYY && ! ('a' | 'b' | ZZZ) | 'something else'
      So shouldn't this be the syntax?
      XXX: YYY ('a' | 'b' | ZZZ) <reject> | 'something' 'else' YYY: 'some string' ZZZ: 'ww' | 'xx' | 'yy' | 'zz'
      I'm not really sure if this is valid but I'll give it a try for now.

      It's pretty confusing actually, because another Production I'd like to write is:

      NonTerminator: SourceCharacter but not LineTerminator
      So this is my first attempt:
      NonTerminator: SourceCharacter | SourceCharacter LineTerminator <reject>
      Anyone think this is correct? or is it:
      NonTerminator: SourceCharacter LineTerminator <reject>
      somehow I do not think the second one is correct...

      Does the <reject> apply to the entire line or just the item that it follows?

Re: Parse::RecDescent - Any Way to do a Negation?
by Masem (Monsignor) on Mar 14, 2002 at 02:39 UTC
    Take a look at the 'reject' keyword. I've not used it myself, but the docs suggest that you can use it to have both successful and unsuccessful matches work. However, as a precaution, because P:RD is inching left-to-right, to get the exact action you need may be impossible.

    Dr. Michael K. Neylon - || "You've left the lens cap of your mind on again, Pinky" - The Brain
    "I can see my house from here!"
    It's not what you know, but knowing how to find it if you don't know that's important

•Re: Parse::RecDescent - Any Way to do a Negation?
by merlyn (Sage) on Mar 14, 2002 at 13:42 UTC
    Well, I'm merely a demi-god of Parse::RecDescent {grin}, but I'd say a negative lookahead is what you need.
    XXX: ...!('a' | 'this string' | ZZZ) YYY | 'something' 'else' YYY: 'some string' ZZZ: 'ww' | 'xx' | 'yy' | 'zz'
    Beware that this is probably pretty slow.

    -- Randal L. Schwartz, Perl hacker

Re: Parse::RecDescent - Any Way to do a Negation?
by princepawn (Parson) on Mar 14, 2002 at 16:06 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://151578]
Approved by root
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (7)
As of 2017-07-21 07:00 GMT
Find Nodes?
    Voting Booth?
    I came, I saw, I ...

    Results (319 votes). Check out past polls.