Пример #1
0
        // reads a STON address path segment
        private IStonPathSegment ReadPathSegment(StonTokenReader reader)
        {
            int pathOpen = reader.ExpectAndSkip(StonChartype.PathSegmentBegin);

            if (pathOpen == '.')
            {
                // ancestor access segment
                if (reader.TryAndSkip(StonChartype.AncestorAccess))
                {
                    int ancestorOrder = 1;
                    while (reader.TryAndSkip(StonChartype.AncestorAccess))
                    {
                        ++ancestorOrder;
                    }
                    return(ElementFactory.CreateAncestorPathSegment(ancestorOrder));
                }
                // named member access segment
                else
                {
                    return(ElementFactory.CreateMemberPathSegment(ReadBindingName(reader)));
                }
            }
            else
            {
                // collection element access segment
                if (reader.TryAndSkip(StonChartype.PathSegmentCollection))
                {
                    int currentPosition = reader.Position;
                    int currentLine     = reader.Line;
                    int currentColumn   = reader.Column;

                    if (reader.Peek().HasChartype(StonChartype.Sign))
                    {
                        if (reader.Peek() == '-')
                        {
                            throw new StonParsingException(currentPosition, currentLine, currentColumn, "Collection element index cannot be negative.");
                        }
                        reader.ReadAndSkip();
                        if (!reader.Peek().HasChartype(StonChartype.Digit))
                        {
                            throw reader.MakeUnexpectedCharacterException(StonChartype.Digit);
                        }
                    }

                    IStonEntity elementIndex;
                    // number or binary integer index
                    if (reader.Peek().HasChartype(StonChartype.ZeroDigit))
                    {
                        reader.ReadAndSkip();
                        if (reader.Peek().HasChartype(StonChartype.BaseIdentifier))
                        {
                            elementIndex = ElementFactory.CreateSimpleEntity(ElementFactory.CreateSimpleValue(StonDataType.Binary, reader.ReadBinaryContent(false)));
                        }
                        else
                        {
                            elementIndex = ElementFactory.CreateSimpleEntity(ElementFactory.CreateSimpleValue(StonDataType.Number, reader.ReadNumberContent(false)));
                        }
                    }
                    // number integer index
                    else if (reader.Peek().HasChartype(StonChartype.NonZeroDigit))
                    {
                        elementIndex = ElementFactory.CreateSimpleEntity(ElementFactory.CreateSimpleValue(StonDataType.Number, reader.ReadNumberContent(false)));
                    }
                    // resolved reference index
                    else if (reader.Peek().HasChartype(StonChartype.AddressBegin))
                    {
                        elementIndex = ElementFactory.CreateReferenceEntity(ReadAddress(reader));
                    }
                    else
                    {
                        throw reader.MakeUnexpectedCharacterException(StonChartype.Digit | StonChartype.AddressBegin | StonChartype.Sign);
                    }

                    reader.ExpectAndSkip(StonChartype.IndexClose);
                    return(ElementFactory.CreateCollectionElementPathSegment(elementIndex));
                }
                // index member access segment
                else
                {
                    IEnumerable <IStonEntity> indexParameters = ReadSequence(reader, ReadAddressEntity, StonChartype.IndexClose);
                    return(ElementFactory.CreateMemberPathSegment(ElementFactory.CreateBindingIndex(indexParameters)));
                }
            }
        }