Example #1
0
        //  parameter ::=
        //      identifier | "(" sublist ")"
        private Parameter ParseParameter(int position, HashSet<string> names, ParameterKind kind, bool isTyped = false) {
            Name name;
            Parameter parameter;

            if (PeekToken().Kind == TokenKind.LeftParenthesis) {
                // sublist
                string parenWhiteSpace = _lookaheadWhiteSpace;

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

                if (_langVersion.Is3x()) {
                    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);
                    }
                }
            } else if ((name = TokenToName(PeekToken())).HasName) {
                NextToken();
                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.Is2x()) {
                        ReportSyntaxError(start, parameter.Annotation.EndIndex, "invalid syntax, parameter annotations require 3.x");
                    }
                }
                CompleteParameterName(parameter, name.RealName, names, paramStart);
            } else {
                ReportSyntaxError(_lookahead);
                NextToken();
                parameter = new ErrorParameter(_verbatim ? Error(_tokenWhiteSpace + _token.Token.VerbatimImage) : null);
            }

            return parameter;
        }
Example #2
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.Is3x()) {
                        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.Is2x()) {
                    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();
        }