// dict_display: '{' [dictorsetmaker] '}' // dictorsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | // (test (comp_for | (',' test)* [','])) ) private Expression FinishDictOrSetValue() { var oStart = GetStart(); var oEnd = GetEnd(); List<SliceExpression> dictMembers = null; List<Expression> setMembers = null; bool prevAllow = _allowIncomplete; try { _allowIncomplete = true; while (true) { if (MaybeEat(TokenKind.RightBrace)) { // empty dict literal break; } bool first = false; Expression e1 = ParseExpression(); if (MaybeEat(TokenKind.Colon)) { // dict literal if (setMembers != null) { ReportSyntaxError("invalid syntax"); } else if (dictMembers == null) { dictMembers = new List<SliceExpression>(); first = true; } Expression e2 = ParseExpression(); if (PeekToken(Tokens.KeywordForToken)) { if (!first) { ReportSyntaxError("invalid syntax"); } return FinishDictComp(e1, e2, oStart, oEnd); } SliceExpression se = new SliceExpression(e1, e2, null, false); se.SetLoc(_globalParent, e1.StartIndex, e2.EndIndex); dictMembers.Add(se); } else { // set literal if (dictMembers != null) { ReportSyntaxError("invalid syntax"); } else if (setMembers == null) { setMembers = new List<Expression>(); first = true; } if (PeekToken(Tokens.KeywordForToken)) { if (!first) { ReportSyntaxError("invalid syntax"); } return FinishSetComp(e1, oStart, oEnd); } // error recovery if (setMembers != null) { setMembers.Add(e1); } } if (!MaybeEat(TokenKind.Comma)) { Eat(TokenKind.RightBrace); break; } } } finally { _allowIncomplete = prevAllow; } var cStart = GetStart(); var cEnd = GetEnd(); if (_sink != null) { _sink.MatchPair( new SourceSpan(_tokenizer.IndexToLocation(oStart), _tokenizer.IndexToLocation(oEnd)), new SourceSpan(_tokenizer.IndexToLocation(cStart), _tokenizer.IndexToLocation(cEnd)), 1 ); } if (dictMembers != null || setMembers == null) { SliceExpression[] exprs; if (dictMembers != null) { exprs = dictMembers.ToArray(); } else { exprs = new SliceExpression[0]; } DictionaryExpression ret = new DictionaryExpression(exprs); ret.SetLoc(_globalParent, oStart, cEnd); return ret; } else { SetExpression ret = new SetExpression(setMembers.ToArray()); ret.SetLoc(_globalParent, oStart, cEnd); return ret; } }