Ejemplo n.º 1
0
        private static ParseResult TryParseIdentifier <TChars>(
            ExpandedTokenData <TChars> token,
            PipExecutionContext context,
            ref int position,
            out TChars identifier,
            bool logErrors = true)
            where TChars : struct, ICharSpan <TChars>
        {
            Contract.Requires(token.IsValid);
            Contract.RequiresNotNull(context);

            var pathTable = context.PathTable;

            var text = token.Text;

            if (text.Length == 0 || position == text.Length)
            {
                var updateToken = token.UpdateLineInformationForPosition(position);
                identifier = default(TChars);
                return(new ParseResult()
                {
                    Status = ParseStatus.UnexpectedEmptyIdentifier,
                    Path = updateToken.Path.ToString(pathTable),
                    Line = updateToken.Line,
                    Position = updateToken.Position,
                });
            }

            int firstPosition = position;

            char firstChar = text[position];

            if (!SymbolCharacters.IsValidStartChar(firstChar))
            {
                var updateToken = token.UpdateLineInformationForPosition(position);
                identifier = default(TChars);
                return(new ParseResult()
                {
                    Status = ParseStatus.UnexpectedCharacterAtStartOfIdentifier,
                    Path = updateToken.Path.ToString(pathTable),
                    Line = updateToken.Line,
                    Position = updateToken.Position,
                    Text = firstChar.ToString(),
                });
            }

            position++;

            for (; position < text.Length; position++)
            {
                char ch = text[position];
                if (!SymbolCharacters.IsValidChar(ch))
                {
                    break;
                }
            }

            identifier = text.Subsegment(firstPosition, position - firstPosition);
            return(new ParseResult {
                Status = ParseStatus.Success
            });
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Parses a dotted identifier. All error logging is the responsibility of the caller
        /// </summary>
        /// <param name="token">The token to parse</param>
        /// <param name="context">Context with tables.</param>
        /// <param name="identifier">The parsed identifier if successful, null if not.</param>
        public static ParseResult TryParse <TChars>(
            ExpandedTokenData <TChars> token,
            PipExecutionContext context,
            out DottedIdentifier identifier)
            where TChars : struct, ICharSpan <TChars>
        {
            Contract.Requires(token.IsValid);
            Contract.RequiresNotNull(context);

            PathTable   pathTableForError = context.PathTable;
            SymbolTable symbolTable       = context.SymbolTable;

            int position = 0;

            var text       = token.Text;
            int textLength = text.Length;

            identifier = null;

            if (text.Length == 0)
            {
                return(new ParseResult()
                {
                    Status = ParseStatus.InvalidDottedIdentifierCannotBeEmpty,
                    Path = token.Path.ToString(pathTableForError),
                    Line = token.Line,
                    Position = token.Position,
                });
            }

            TChars id;
            var    parseIdenfierResult = TryParseIdentifier(token, context, ref position, out id);

            if (parseIdenfierResult.Status != ParseStatus.Success)
            {
                return(parseIdenfierResult);
            }

            identifier = DottedIdentifier.Create(symbolTable, id);
            DottedIdentifier currentIdentifier = identifier;

            while (position < textLength)
            {
                if (text[position] == '.')
                {
                    if (position == textLength - 1)
                    {
                        // Last char is a dot.
                        var updateToken = token.UpdateLineInformationForPosition(position);
                        identifier = null;
                        return(new ParseResult()
                        {
                            Status = ParseStatus.InvalidDottedIdentifierUnexpectedDot,
                            Path = updateToken.Path.ToString(pathTableForError),
                            Line = updateToken.Line,
                            Position = updateToken.Position,
                            Text = currentIdentifier != null?currentIdentifier.Head.ToString(symbolTable.StringTable) : string.Empty,
                        });
                    }

                    position++;

                    TChars currentId;
                    parseIdenfierResult = TryParseIdentifier(token, context, ref position, out currentId);
                    if (parseIdenfierResult.Status != ParseStatus.Success)
                    {
                        identifier = null;
                        return(parseIdenfierResult);
                    }

                    var tail = DottedIdentifier.Create(symbolTable, currentId);
                    currentIdentifier.m_tail = tail;
                    currentIdentifier        = tail;
                }
                else
                {
                    break;
                }
            }

            if (position < textLength)
            {
                var updateToken = token.UpdateLineInformationForPosition(position);
                identifier = null;

                return(new ParseResult()
                {
                    Status = ParseStatus.InvalidDottedIdentifierUnexpectedCharacter,
                    Path = updateToken.Path.ToString(pathTableForError),
                    Line = updateToken.Line,
                    Position = updateToken.Position,
                    Text = text[position].ToString(),
                });
            }

            return(new ParseResult()
            {
                Status = ParseStatus.Success
            });
        }