[cfe-commits] [PATCH] Parsing C++0x lambda expressions
John Freeman
jfreeman at cse.tamu.edu
Wed Jul 6 14:00:20 PDT 2011
Thanks for the review, Doug! Some more discussion below:
> +/// isCXX0XLambdaExpression - Make sure we are looking at a C++ lambda
> +/// expression and not a (possibly nested) Objective-C++ message expression.
> +bool Parser::isCXX0XLambdaExpression() {
> + assert(getLang().CPlusPlus0x
> +&& Tok.is(tok::l_square)
> +&& "why would you call me?");
> + // FIXME: Is there a smaller set of conditions we can check?
> + return !getLang().ObjC1
> + || NextToken().is(tok::r_square)
> + || NextToken().is(tok::equal)
> + || NextToken().is(tok::amp)
> + || (NextToken().is(tok::identifier)
> +&& (GetLookAheadToken(2).is(tok::comma)
> + || GetLookAheadToken(2).is(tok::r_square)));
>
> This isn't quite enough, because of the comma operator:
>
> [x,y method:17]
>
> To catch this evil case, you're going to need tentative parsing… but only after you've done a quick check for the common/easy cases.
Ok. Could you take a look at my tentative parsing questions on cfe-dev?
Particularly, are diagnostics suppressed until parsing has been
committed, or do I need to remove diagnostics from tentative parsing?
Some errors could be slight enough that they don't mean I'm not parsing
a lambda-introducer, like if '&' is followed by 'this'. I'd like to
diagnose them, but have just one convenient place to commit to parsing
(at the end). Is that possible? What is the convention? Should I try to
commit to parsing as early as possible?
> + bool first = true;
> + while (Tok.isNot(tok::r_square)) {
> + if (first) {
> + first = false;
> +
> + // Parse capture-default.
> + if (Tok.is(tok::amp)&& NextToken().isNot(tok::identifier)) {
> + List.Default = DEFAULT_CAPTURE_BY_REF;
> + } else if (Tok.is(tok::equal)) {
> + List.Default = DEFAULT_CAPTURE_BY_COPY;
> + }
> +
> + if (List.Default != DEFAULT_CAPTURE_NONE) {
> + // Consume '&' or '='.
> + ConsumeToken();
> + continue;
> + }
> + } else {
> + if (ExpectAndConsume(tok::comma,
> + diag::err_expected_comma,
> + "",
> + tok::r_square)) {
> + // FIXME: We could also expect end of capture list. Should the
> + // diagnostic indicate this?
> + return ExprError();
> + }
> + }
>
> I find this logic to be a bit twisty. Why not do an initial check for& (followed by non-identifier) or = to set the default capture kind, then go into the loop that handles individual captures?
I believe it will still require some twisty logic. What will the loop
handle? If it succeeds on an empty list, then we will need special logic
if the default is followed by a comma but no capture past that. If it
succeeds only on a non-empty list, then we will need special logic for
an empty list. I thought this was the best solution.
- John
More information about the cfe-commits
mailing list