Ejemplo n.º 1
0
        //varargslist: (fpdef ['=' expression ] ',')* ('*' NAME [',' '**' NAME] | '**' NAME) | fpdef ['=' expression] (',' fpdef ['=' expression])* [',']
        //fpdef: NAME | '(' fplist ')'
        //fplist: fpdef (',' fpdef)* [',']
        private Parameter[] ParseVarArgsList(TokenKind terminator, out List<string> commaWhiteSpace, out bool ateTerminator, bool isTyped = false)
        {
            // parameters not doing * or ** today
            List<Parameter> pl = new List<Parameter>();
            commaWhiteSpace = MakeWhiteSpaceList();
            HashSet<string> names = new HashSet<string>(StringComparer.Ordinal);
            bool needDefault = false, parsedStarArgs = false;
            string namedOnlyText = null;
            for (int position = 0; ; position++) {
                if (MaybeEat(terminator)) {
                    ateTerminator = true;
                    break;
                }

                Parameter parameter;

                var lookahead = _lookahead;
                if (MaybeEat(TokenKind.Multiply)) {
                    string starWhiteSpace = _tokenWhiteSpace;
                    if (parsedStarArgs) {
                        ReportSyntaxError(lookahead.Span.Start, GetEnd(), "duplicate * args arguments");
                    }
                    parsedStarArgs = true;

                    if (_langVersion.Is7x()) {
                        if (MaybeEat(TokenKind.Comma)) {
                            string namedOnlyWhiteSpace = _tokenWhiteSpace;
                            // bare *
                            if (MaybeEat(terminator)) {
                                ReportSyntaxError(lookahead.Span.Start, GetEnd(), "named arguments must follow bare *");
                                ateTerminator = true;
                                break;
                            }
                            if (_verbatim) {
                                namedOnlyText = starWhiteSpace + "*" + namedOnlyWhiteSpace + ",";
                            }
                            continue;
                        }
                    }

                    parameter = ParseParameterName(names, ParameterKind.List, isTyped);
                    if (parameter == null) {
                        // no parameter name, syntax error
                        parameter = new ErrorParameter(Error(starWhiteSpace + "*" + _lookaheadWhiteSpace + _lookahead.Token.VerbatimImage));
                        NextToken();
                    } else if (_verbatim) {
                        AddPreceedingWhiteSpace(parameter, starWhiteSpace);
                    }

                    if (namedOnlyText != null) {
                        if (_verbatim) {
                            AddExtraVerbatimText(parameter, namedOnlyText);
                        }
                        namedOnlyText = null;
                    }

                    pl.Add(parameter);

                    if (!MaybeEat(TokenKind.Comma)) {
                        ateTerminator = Eat(terminator);
                        break;
                    }

                    if (commaWhiteSpace != null) {
                        commaWhiteSpace.Add(_tokenWhiteSpace);
                    }

                    continue;
                } else if (MaybeEat(TokenKind.Power)) {
                    string starStarWhiteSpace = _tokenWhiteSpace;
                    parameter = ParseParameterName(names, ParameterKind.Dictionary, isTyped);
                    if (parameter == null) {
                        // no parameter name, syntax error
                        parameter = new ErrorParameter(Error(starStarWhiteSpace + "**" + _lookaheadWhiteSpace + _lookahead.Token.VerbatimImage));
                        NextToken();
                    }
                    pl.Add(parameter);
                    if (_verbatim) {
                        AddPreceedingWhiteSpace(parameter, starStarWhiteSpace);
                    }
                    ateTerminator = Eat(terminator);

                    if (namedOnlyText != null) {
                        if (_verbatim) {
                            AddExtraVerbatimText(parameter, namedOnlyText);
                        }
                        namedOnlyText = null;
                    }
                    break;
                }

                //
                //  Parsing defparameter:
                //
                //  defparameter ::=
                //      parameter ["=" expression]

                parameter = ParseParameter(position, names, parsedStarArgs ? ParameterKind.KeywordOnly : ParameterKind.Normal, isTyped);
                pl.Add(parameter);
                if (MaybeEat(TokenKind.Assign)) {
                    if (_verbatim) {
                        AddSecondPreceedingWhiteSpace(parameter, _tokenWhiteSpace);
                    }
                    needDefault = true;
                    parameter.DefaultValue = ParseExpression();
                    parameter.EndIndex = parameter.DefaultValue.EndIndex;
                } else if (needDefault && !parsedStarArgs) {
                    ReportSyntaxError(parameter.StartIndex, parameter.EndIndex, "default value must be specified here");
                }

                if (namedOnlyText != null) {
                    if (_verbatim) {
                        AddExtraVerbatimText(parameter, namedOnlyText);
                    }
                    namedOnlyText = null;
                }

                if (parsedStarArgs && _langVersion.Is6x()) {
                    ReportSyntaxError(parameter.StartIndex, GetEnd(), "positional parameter after * args not allowed");
                }

                if (!MaybeEat(TokenKind.Comma)) {
                    ateTerminator = Eat(terminator);
                    break;
                }

                if (commaWhiteSpace != null) {
                    commaWhiteSpace.Add(_tokenWhiteSpace);
                }
            }

            return pl.ToArray();
        }
Ejemplo n.º 2
0
        //  parameter ::=
        //      identifier | "(" sublist ")"
        private Parameter ParseParameter(int position, HashSet<string> names, ParameterKind kind, bool isTyped = false)
        {
            Token t = PeekToken();
            Parameter parameter;

            switch (t.Kind) {
                case TokenKind.LeftParenthesis: // sublist
                    string parenWhiteSpace = _lookaheadWhiteSpace;

                    NextToken();
                    var parenStart = GetStart();
                    Expression ret = ParseSublist(names, true);

                    if (_langVersion.Is7x()) {
                        ReportSyntaxError(parenStart, GetEnd(), "sublist parameters are not supported in 3.x");
                    }

                    bool ateRightParen = Eat(TokenKind.RightParenthesis);
                    string closeParenWhiteSpace = _tokenWhiteSpace;

                    TupleExpression tret = ret as TupleExpression;
                    NameExpression nameRet;

                    if (tret != null) {
                        parameter = new SublistParameter(position, tret);
                        if (_verbatim) {
                            AddPreceedingWhiteSpace(tret, parenWhiteSpace);
                            AddSecondPreceedingWhiteSpace(tret, closeParenWhiteSpace);
                            if (!ateRightParen) {
                                AddErrorMissingCloseGrouping(parameter);
                            }
                        }
                    } else if ((nameRet = ret as NameExpression) != null) {
                        parameter = new Parameter(nameRet.Name, kind);
                        if (_verbatim) {
                            AddThirdPreceedingWhiteSpace(parameter,  (string) _attributes[nameRet][NodeAttributes.PreceedingWhiteSpace]);
                            AddIsAltForm(parameter);
                            if (!ateRightParen) {
                                AddErrorMissingCloseGrouping(parameter);
                            }
                        }
                    } else {
                        Debug.Assert(ret is ErrorExpression);
                        ReportSyntaxError(_lookahead);

                        parameter = new ErrorParameter((ErrorExpression)ret);
                        AddIsAltForm(parameter);
                    }

                    if (parameter != null) {
                        parameter.SetLoc(ret.IndexSpan);
                    }
                    if (_verbatim) {
                        AddPreceedingWhiteSpace(parameter, parenWhiteSpace);
                        AddSecondPreceedingWhiteSpace(parameter, closeParenWhiteSpace);
                        if (!ateRightParen) {
                            AddErrorMissingCloseGrouping(parameter);
                        }
                    }

                    break;

                case TokenKind.Name:  // identifier
                    NextToken();
                    var name = TokenToName((NameToken)t);
                    var paramStart = GetStart();
                    parameter = new Parameter(name.RealName, kind);
                    if (_verbatim) {
                        AddPreceedingWhiteSpace(parameter, _tokenWhiteSpace);
                        AddVerbatimName(name, parameter);
                    }
                    if (isTyped && MaybeEat(TokenKind.Colon)) {
                        if (_verbatim) {
                            AddThirdPreceedingWhiteSpace(parameter, _tokenWhiteSpace);
                        }

                        var start = GetStart();
                        parameter.Annotation = ParseExpression();

                        if (_langVersion.Is6x()) {
                            ReportSyntaxError(start, parameter.Annotation.EndIndex, "invalid syntax, parameter annotations require 3.x");
                        }
                    }
                    CompleteParameterName(parameter, name.RealName, names, paramStart);
                    break;

                default:
                    ReportSyntaxError(_lookahead);
                    NextToken();
                    parameter = new ErrorParameter(_verbatim ? Error(_tokenWhiteSpace + _token.Token.VerbatimImage) : null);
                    break;
            }

            return parameter;
        }