// primary: atom | attributeref | subscription | slicing | call // atom: identifier | literal | enclosure // enclosure: // parenth_form | // list_display | // generator_expression | // dict_display | // string_conversion | // yield_atom private Expression ParsePrimary() { Token t = PeekToken(); Expression ret; switch (t.Kind) { case TokenKind.LeftParenthesis: // parenth_form, generator_expression, yield_atom NextToken(); return FinishTupleOrGenExp(); case TokenKind.LeftBracket: // list_display NextToken(); return FinishListValue(); case TokenKind.LeftBrace: // dict_display NextToken(); return FinishDictOrSetValue(); case TokenKind.BackQuote: // string_conversion NextToken(); return FinishStringConversion(); case TokenKind.KeywordAsync: case TokenKind.KeywordAwait: // if we made it this far, treat await and async as names // See ParseAwaitExpr() for treating 'await' as a keyword case TokenKind.Name: // identifier NextToken(); ret = MakeName(TokenToName(t)); if (_verbatim) { AddPreceedingWhiteSpace(ret); } ret.SetLoc(GetStart(), GetEnd()); return ret; case TokenKind.Ellipsis: NextToken(); ret = new ConstantExpression(Ellipsis.Value); if (_verbatim) { AddPreceedingWhiteSpace(ret, _tokenWhiteSpace); } ret.SetLoc(GetStart(), GetEnd()); return ret; case TokenKind.KeywordTrue: NextToken(); ret = new ConstantExpression(true); if (_verbatim) { AddPreceedingWhiteSpace(ret); } ret.SetLoc(GetStart(), GetEnd()); return ret; case TokenKind.KeywordFalse: NextToken(); ret = new ConstantExpression(false); if (_verbatim) { AddPreceedingWhiteSpace(ret); } ret.SetLoc(GetStart(), GetEnd()); return ret; case TokenKind.Constant: // literal NextToken(); var start = GetStart(); object cv = t.Value; string cvs = cv as string; AsciiString bytes; if (PeekToken() is ConstantValueToken && (cv is string || cv is AsciiString)) { // string plus string[] verbatimImages = null, verbatimWhiteSpace = null; if (cvs != null) { cv = FinishStringPlus(cvs, t, out verbatimImages, out verbatimWhiteSpace); } else if ((bytes = cv as AsciiString) != null) { cv = FinishBytesPlus(bytes, t, out verbatimImages, out verbatimWhiteSpace); } ret = new ConstantExpression(cv); if (_verbatim) { AddListWhiteSpace(ret, verbatimWhiteSpace); AddVerbatimNames(ret, verbatimImages); } } else { ret = new ConstantExpression(cv); if (_verbatim) { AddExtraVerbatimText(ret, t.VerbatimImage); AddPreceedingWhiteSpace(ret, _tokenWhiteSpace); } } ret.SetLoc(start, GetEnd()); return ret; case TokenKind.EndOfFile: // don't eat the end of file token ReportSyntaxError(_lookahead.Token, _lookahead.Span, ErrorCodes.SyntaxError, _allowIncomplete || _tokenizer.EndContinues); // error node return Error(_verbatim ? "" : null); default: ReportSyntaxError(_lookahead.Token, _lookahead.Span, ErrorCodes.SyntaxError, _allowIncomplete || _tokenizer.EndContinues); if (_lookahead.Token.Kind != TokenKind.NewLine) { NextToken(); return Error(_verbatim ? (_tokenWhiteSpace + _token.Token.VerbatimImage) : null); } // error node return Error(""); } }