// trailer: '(' [ arglist_genexpr ] ')' | '[' subscriptlist ']' | '.' NAME private Expression AddTrailers(Expression ret) { while (true) { Token t = PeekToken(); switch (t.Kind) { case TokenKind.LeftParenthesis: NextToken(); Arg[] args = FinishArgListOrGenExpr(); CallExpression call = FinishCallExpr(ret, args); call.SetLoc(GetExternal(), ret.Start, GetEnd()); ret = call; break; case TokenKind.LeftBracket: NextToken(); Expression index = ParseSubscriptList(); IndexExpression ie = new IndexExpression(ret, index); ie.SetLoc(GetExternal(), ret.Start, GetEnd()); ret = ie; break; case TokenKind.Dot: NextToken(); SymbolId name = ReadNameMaybeNone(); FieldExpression fe = new FieldExpression(ret, name); fe.SetLoc(GetExternal(), ret.Start, GetEnd()); ret = fe; break; default: return ret; } } }
// decorators ::= // decorator+ // decorator ::= // "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE private List<Expression> ParseDecorators() { List<Expression> decorators = new List<Expression>(); while (MaybeEat(TokenKind.At)) { Location start = GetStart(); Expression decorator = new NameExpression(ReadName()); decorator.SetLoc(GetExternal(), start, GetEnd()); while (MaybeEat(TokenKind.Dot)) { SymbolId name = ReadNameMaybeNone(); decorator = new FieldExpression(decorator, name); decorator.SetLoc(GetExternal(), GetStart(), GetEnd()); } decorator.SetLoc(GetExternal(), start, GetEnd()); if (MaybeEat(TokenKind.LeftParenthesis)) { context.Sink.StartParameters(GetSpan()); Arg[] args = FinishArgumentList(null); decorator = FinishCallExpr(decorator, args); } decorator.SetLoc(GetExternal(), start, GetEnd()); Eat(TokenKind.NewLine); decorators.Add(decorator); } return decorators; }