New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

`|` with the `pat` macro fragment specifier #4581

Closed
SimonSapin opened this Issue Jan 23, 2013 · 4 comments

Comments

Projects
None yet
4 participants
@SimonSapin
Contributor

SimonSapin commented Jan 23, 2013

Hi,

I made this macro:

macro_rules! is_match(
    ($value:expr, $pattern:pat) => (
        match $value { $pattern => true, _ => false }
    );
)

… which is pretty useful for constructs like if is_match!(next_char(), '0'..'9').
However this does not work with macro "alternatives": if is_match!(next_char(), 'a'..'z' | 'A'..'Z')

error: No rules expected the token: |

Is there a reason this couldn’t work?

@catamorphism

This comment has been minimized.

Show comment
Hide comment
@catamorphism

catamorphism Jan 23, 2013

Contributor

Rust uses the | character to combine patterns in an "or": match color { Red | Green => ..., Blue | Violet => ... }, for example. I don't know enough about the macro-parsing rules to say whether that means it couldn't work in macros, though.

Contributor

catamorphism commented Jan 23, 2013

Rust uses the | character to combine patterns in an "or": match color { Red | Green => ..., Blue | Violet => ... }, for example. I don't know enough about the macro-parsing rules to say whether that means it couldn't work in macros, though.

@SimonSapin

This comment has been minimized.

Show comment
Hide comment
@SimonSapin

SimonSapin Jan 23, 2013

Contributor

Yes @catamorphism. This is exactly the usage of | I want to make, but through a macro.

Contributor

SimonSapin commented Jan 23, 2013

Yes @catamorphism. This is exactly the usage of | I want to make, but through a macro.

@lbonn

This comment has been minimized.

Show comment
Hide comment
@lbonn

lbonn Jan 23, 2013

Contributor

The macro tutorial has an interesting example similar to yours.

I've got this code working:

macro_rules! is_match(
    ($value:expr, [ $($pattern:pat)|+ ]) => (
        match $value { 
            $(
                $pattern => true,
            )+
            _ => false
        }
    );
)

used like this: if is_match!('a', ['a'..'z' | 'A'..'Z']).

I suspect your example doesn't work because pat1 | pat2 is not a pattern in itself.
The match section of the manual is, in my opinion, not very clear on this and I could not find a real definition of pat.

Contributor

lbonn commented Jan 23, 2013

The macro tutorial has an interesting example similar to yours.

I've got this code working:

macro_rules! is_match(
    ($value:expr, [ $($pattern:pat)|+ ]) => (
        match $value { 
            $(
                $pattern => true,
            )+
            _ => false
        }
    );
)

used like this: if is_match!('a', ['a'..'z' | 'A'..'Z']).

I suspect your example doesn't work because pat1 | pat2 is not a pattern in itself.
The match section of the manual is, in my opinion, not very clear on this and I could not find a real definition of pat.

@pnkfelix

This comment has been minimized.

Show comment
Hide comment
@pnkfelix

pnkfelix May 6, 2013

Member

I concur with @lbonn's analysis that vertical-bar (|) is not part of the subgrammar for pat, so you won't inherit the handling of | in your own macro. (Also, if you drop the surrounding [ .. ] from lbonn's definition, then you get something compatible with SimonSapin's original example. Or at least, it seemed to work for me.)

So either this is not-a-bug, or it should be interpreted as a request for a named macro-syntactic-class that contains $($pattern:pat)|+ (but I suspect there is not much value in adding a new named class over just writing the pattern out.)

Issue #2234 is already filed for providing a formal (i.e. EBNF) definition for Rust's grammar, which would presumably help provide more direct answers for these sorts of questions. Since that's already filed, I'm going to close this bug as not-a-bug.

Member

pnkfelix commented May 6, 2013

I concur with @lbonn's analysis that vertical-bar (|) is not part of the subgrammar for pat, so you won't inherit the handling of | in your own macro. (Also, if you drop the surrounding [ .. ] from lbonn's definition, then you get something compatible with SimonSapin's original example. Or at least, it seemed to work for me.)

So either this is not-a-bug, or it should be interpreted as a request for a named macro-syntactic-class that contains $($pattern:pat)|+ (but I suspect there is not much value in adding a new named class over just writing the pattern out.)

Issue #2234 is already filed for providing a formal (i.e. EBNF) definition for Rust's grammar, which would presumably help provide more direct answers for these sorts of questions. Since that's already filed, I'm going to close this bug as not-a-bug.

@pnkfelix pnkfelix closed this May 6, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment