Beispiel #1
0
        public static PkgdefTokenizer Create(int startIndex, string text, Action <PkgdefIssue> onIssue)
        {
            PreCondition.AssertGreaterThanOrEqualTo(startIndex, 0, nameof(startIndex));
            PreCondition.AssertNotNull(text, "text");

            return(PkgdefTokenizer.Create(startIndex, Iterator.Create(text), onIssue));
        }
Beispiel #2
0
        internal static PkgdefRegistryKeyDataItemSegment ParseRegistryKeyDataItem(int startIndex, string text)
        {
            PreCondition.AssertGreaterThanOrEqualTo(startIndex, 0, nameof(startIndex));
            PreCondition.AssertNotNullAndNotEmpty(text, nameof(text));
            PreCondition.AssertOneOf(text[0], "@\"", "text[0]");

            Action <PkgdefIssue> onIssue   = PkgdefDocument.IgnoreIssue;
            PkgdefTokenizer      tokenizer = PkgdefTokenizer.Create(startIndex, text, onIssue);

            tokenizer.Next();
            return(PkgdefDocument.ParseRegistryKeyDataItem(tokenizer, onIssue));
        }
Beispiel #3
0
        private void ReadDigits()
        {
            PreCondition.AssertTrue(this.characters.HasCurrent(), "this.characters.HasCurrent()");
            PreCondition.AssertTrue(PkgdefTokenizer.IsDigit(this.characters.GetCurrent()), "PkgdefTokenizer.IsDigit(this.characters.GetCurrent())");

            int           startIndex = this.characters.GetCurrentIndex();
            StringBuilder builder    = new StringBuilder().Append(this.characters.TakeCurrent());

            while (this.characters.HasCurrent() && PkgdefTokenizer.IsDigit(this.characters.GetCurrent()))
            {
                builder.Append(this.characters.TakeCurrent());
            }

            this.tokenQueue.Enqueue(PkgdefToken.Digits(startIndex, builder.ToString()));
        }
Beispiel #4
0
        /// <summary>
        /// Parse a PkgdefDocument from the provided characters.
        /// </summary>
        /// <param name="iterator">The characters to parse.</param>
        /// <returns>The parsed PkgdefDocument.</returns>
        public static PkgdefDocument Parse(Iterator <char> iterator)
        {
            PreCondition.AssertNotNull(iterator, nameof(iterator));

            List <PkgdefIssue> issues    = new List <PkgdefIssue>();
            PkgdefTokenizer    tokenizer = PkgdefTokenizer.Create(iterator, onIssue: issues.Add);

            tokenizer.EnsureHasStarted();

            List <PkgdefSegment> segments = new List <PkgdefSegment>();

            while (tokenizer.HasCurrent())
            {
                segments.Add(PkgdefDocument.ParseSegment(tokenizer, onIssue: issues.Add));
            }

            return(new PkgdefDocument(segments, issues));
        }
Beispiel #5
0
        private static PkgdefSegment ParseSegment(PkgdefTokenizer tokenizer, Action <PkgdefIssue> onIssue)
        {
            PreCondition.AssertNotNull(tokenizer, nameof(tokenizer));
            PreCondition.AssertTrue(tokenizer.HasCurrent(), "tokenizer.HasCurrent()");
            PreCondition.AssertNotNull(onIssue, nameof(onIssue));

            PkgdefSegment result;

            switch (tokenizer.GetCurrent().GetTokenType())
            {
            case PkgdefTokenType.Whitespace:
                result = PkgdefSegment.Whitespace(tokenizer.GetCurrent().GetStartIndex(), tokenizer.GetCurrent().GetText());
                tokenizer.Next();
                break;

            case PkgdefTokenType.NewLine:
                result = PkgdefSegment.NewLine(tokenizer.GetCurrent().GetStartIndex(), tokenizer.GetCurrent().GetText());
                tokenizer.Next();
                break;

            case PkgdefTokenType.ForwardSlash:
                result = PkgdefDocument.ParseLineComment(tokenizer, onIssue);
                break;

            case PkgdefTokenType.LeftSquareBracket:
                result = PkgdefDocument.ParseRegistryKeyPath(tokenizer, onIssue);
                break;

            case PkgdefTokenType.AtSign:
            case PkgdefTokenType.DoubleQuote:
                result = PkgdefDocument.ParseRegistryKeyDataItem(tokenizer, onIssue);
                break;

            default:
                result = PkgdefSegment.Unrecognized(tokenizer.GetCurrent().GetStartIndex(), tokenizer.GetCurrent().GetText());
                tokenizer.Next();
                break;
            }

            return(result);
        }
Beispiel #6
0
        private void ReadWhitespace()
        {
            PreCondition.AssertTrue(this.characters.HasCurrent(), "this.characters.HasCurrent()");
            PreCondition.AssertTrue(PkgdefTokenizer.IsWhitespaceCharacter(this.characters.GetCurrent()), "PkgdefTokenizer.IsWhitespaceCharacter(this.characters.GetCurrent())");

            PkgdefToken   newLineToken = null;
            int           startIndex   = this.characters.GetCurrentIndex();
            StringBuilder builder      = new StringBuilder();

            while (this.characters.HasCurrent() && PkgdefTokenizer.IsWhitespaceCharacter(this.characters.GetCurrent()))
            {
                if (this.characters.GetCurrent() != '\r')
                {
                    builder.Append(this.characters.TakeCurrent());
                }
                else
                {
                    int newLineStartIndex = this.characters.GetCurrentIndex();
                    if (this.characters.Next() && this.characters.GetCurrent() == '\n')
                    {
                        newLineToken = PkgdefToken.NewLine(newLineStartIndex, "\r\n");
                        this.characters.Next();
                        break;
                    }
                    else
                    {
                        builder.Append('\r');
                    }
                }
            }

            if (builder.Length > 0)
            {
                this.tokenQueue.Enqueue(PkgdefToken.Whitespace(startIndex, builder.ToString()));
            }
            if (newLineToken != null)
            {
                this.tokenQueue.Enqueue(newLineToken);
            }
        }
Beispiel #7
0
        internal static PkgdefRegistryKeyPathSegment ParseRegistryKeyPath(PkgdefTokenizer tokenizer, Action <PkgdefIssue> onIssue)
        {
            PreCondition.AssertNotNull(tokenizer, nameof(tokenizer));
            PreCondition.AssertTrue(tokenizer.HasCurrent(), "tokenizer.HasCurrent()");
            PreCondition.AssertEqual(tokenizer.GetCurrent().GetTokenType(), PkgdefTokenType.LeftSquareBracket, "tokenizer.GetCurrent().GetTokenType()");
            PreCondition.AssertNotNull(onIssue, nameof(onIssue));

            List <PkgdefToken> tokens = new List <PkgdefToken>()
            {
                tokenizer.TakeCurrent()
            };

            while (tokenizer.HasCurrent())
            {
                PkgdefTokenType tokenType = tokenizer.GetCurrent().GetTokenType();
                if (tokenType == PkgdefTokenType.NewLine)
                {
                    break;
                }
                else
                {
                    tokens.Add(tokenizer.TakeCurrent());
                    if (tokenType == PkgdefTokenType.RightSquareBracket)
                    {
                        break;
                    }
                }
            }

            PkgdefRegistryKeyPathSegment result = new PkgdefRegistryKeyPathSegment(tokens);

            if (result.GetRightSquareBracket() == null)
            {
                onIssue(new PkgdefIssue(result.GetStartIndex(), result.GetLength(), "Missing registry key path right square bracket (']')."));
            }

            return(result);
        }
Beispiel #8
0
        internal static PkgdefSegment ParseLineComment(PkgdefTokenizer tokenizer, Action <PkgdefIssue> onIssue)
        {
            PreCondition.AssertNotNull(tokenizer, nameof(tokenizer));
            PreCondition.AssertTrue(tokenizer.HasCurrent(), "tokenizer.HasCurrent()");
            PreCondition.AssertEqual(tokenizer.GetCurrent().GetTokenType(), PkgdefTokenType.ForwardSlash, "tokenizer.GetCurrent().GetTokenType()");
            PreCondition.AssertNotNull(onIssue, nameof(onIssue));

            PkgdefSegment result;
            int           startIndex = tokenizer.TakeCurrent().GetStartIndex();
            StringBuilder builder    = new StringBuilder().Append('/');

            if (!tokenizer.HasCurrent())
            {
                onIssue(new PkgdefIssue(startIndex, 1, "Missing line-comment's second forward slash ('/')."));
                result = PkgdefSegment.Unrecognized(startIndex, builder.ToString());
            }
            else if (tokenizer.GetCurrent().GetTokenType() != PkgdefTokenType.ForwardSlash)
            {
                onIssue.Invoke(new PkgdefIssue(startIndex + 1, 1, "Expected line-comment's second forward slash ('/')."));
                result = PkgdefSegment.Unrecognized(startIndex, builder.ToString());
            }
            else
            {
                builder.Append('/');
                tokenizer.Next();

                while (tokenizer.HasCurrent() && tokenizer.GetCurrent().GetTokenType() != PkgdefTokenType.NewLine)
                {
                    builder.Append(tokenizer.TakeCurrent().GetText());
                }
                string text = builder.ToString();
                result = PkgdefSegment.LineComment(startIndex, text);
            }

            return(result);
        }
Beispiel #9
0
        /// <inheritdoc/>
        public override bool MoveNext()
        {
            this.characters.EnsureHasStarted();
            this.hasStarted = true;

            if (this.HasCurrent())
            {
                this.tokenQueue.Dequeue();
            }

            if (this.characters.HasCurrent())
            {
                switch (this.characters.GetCurrent())
                {
                case '/':
                    this.tokenQueue.Enqueue(PkgdefToken.ForwardSlash(this.characters.GetCurrentIndex()));
                    this.characters.Next();
                    break;

                case '\\':
                    this.tokenQueue.Enqueue(PkgdefToken.Backslash(this.characters.GetCurrentIndex()));
                    this.characters.Next();
                    break;

                case '\"':
                    this.tokenQueue.Enqueue(PkgdefToken.DoubleQuote(this.characters.GetCurrentIndex()));
                    this.characters.Next();
                    break;

                case '@':
                    this.tokenQueue.Enqueue(PkgdefToken.AtSign(this.characters.GetCurrentIndex()));
                    this.characters.Next();
                    break;

                case '\n':
                    this.tokenQueue.Enqueue(PkgdefToken.NewLine(this.characters.GetCurrentIndex(), "\n"));
                    this.characters.Next();
                    break;

                case '=':
                    this.tokenQueue.Enqueue(PkgdefToken.EqualsSign(this.characters.GetCurrentIndex()));
                    this.characters.Next();
                    break;

                case '$':
                    this.tokenQueue.Enqueue(PkgdefToken.DollarSign(this.characters.GetCurrentIndex()));
                    this.characters.Next();
                    break;

                case '[':
                    this.tokenQueue.Enqueue(PkgdefToken.LeftSquareBracket(this.characters.GetCurrentIndex()));
                    this.characters.Next();
                    break;

                case ']':
                    this.tokenQueue.Enqueue(PkgdefToken.RightSquareBracket(this.characters.GetCurrentIndex()));
                    this.characters.Next();
                    break;

                case ':':
                    this.tokenQueue.Enqueue(PkgdefToken.Colon(this.characters.GetCurrentIndex()));
                    this.characters.Next();
                    break;

                case '{':
                    this.tokenQueue.Enqueue(PkgdefToken.LeftCurlyBracket(this.characters.GetCurrentIndex()));
                    this.characters.Next();
                    break;

                case '}':
                    this.tokenQueue.Enqueue(PkgdefToken.RightCurlyBracket(this.characters.GetCurrentIndex()));
                    this.characters.Next();
                    break;

                case '-':
                    this.tokenQueue.Enqueue(PkgdefToken.Dash(this.characters.GetCurrentIndex()));
                    this.characters.Next();
                    break;

                default:
                    if (PkgdefTokenizer.IsWhitespaceCharacter(this.characters.GetCurrent()))
                    {
                        this.ReadWhitespace();
                    }
                    else if (PkgdefTokenizer.IsLetter(this.characters.GetCurrent()))
                    {
                        this.ReadLetters();
                    }
                    else if (PkgdefTokenizer.IsDigit(this.characters.GetCurrent()))
                    {
                        this.ReadDigits();
                    }
                    else
                    {
                        this.tokenQueue.Enqueue(PkgdefToken.Unrecognized(characters.GetCurrentIndex(), characters.GetCurrent()));
                        this.characters.Next();
                    }
                    break;
                }
            }

            return(this.HasCurrent());
        }
Beispiel #10
0
        public static PkgdefTokenizer Create(string text, Action <PkgdefIssue> onIssue)
        {
            PreCondition.AssertNotNull(text, "text");

            return(PkgdefTokenizer.Create(Iterator.Create(text), onIssue));
        }
Beispiel #11
0
        internal static PkgdefRegistryKeyDataItemSegment ParseRegistryKeyDataItem(PkgdefTokenizer tokenizer, Action <PkgdefIssue> onIssue)
        {
            PreCondition.AssertNotNull(tokenizer, nameof(tokenizer));
            PreCondition.AssertTrue(tokenizer.HasCurrent(), "tokenizer.HasCurrent()");
            PreCondition.AssertOneOf(tokenizer.GetCurrent().GetTokenType(), new[] { PkgdefTokenType.AtSign, PkgdefTokenType.DoubleQuote }, "tokenizer.GetCurrent().GetTokenType()");
            PreCondition.AssertNotNull(onIssue, nameof(onIssue));

            PkgdefToken        registryKeyDataItemNameFirstToken = tokenizer.TakeCurrent();
            List <PkgdefToken> tokens = new List <PkgdefToken>()
            {
                registryKeyDataItemNameFirstToken
            };
            bool dataItemDone = false;

            if (registryKeyDataItemNameFirstToken.GetTokenType() == PkgdefTokenType.DoubleQuote)
            {
                if (!tokenizer.HasCurrent())
                {
                    onIssue(new PkgdefIssue(registryKeyDataItemNameFirstToken.GetStartIndex(), registryKeyDataItemNameFirstToken.GetLength(), "Missing registry key data item name closing double-quote ('\"')."));
                    dataItemDone = true;
                }
                else
                {
                    while (tokenizer.HasCurrent())
                    {
                        PkgdefTokenType tokenType = tokenizer.GetCurrent().GetTokenType();
                        if (tokenType == PkgdefTokenType.NewLine)
                        {
                            onIssue(new PkgdefIssue(PkgdefToken.GetStartIndex(tokens), PkgdefToken.GetLength(tokens), "Missing registry key data item name closing double-quote ('\"')."));
                            dataItemDone = true;
                            break;
                        }
                        else
                        {
                            PkgdefToken token = tokenizer.TakeCurrent();
                            tokens.Add(token);
                            if (token.GetTokenType() == PkgdefTokenType.DoubleQuote)
                            {
                                break;
                            }
                        }
                    }
                }
            }

            if (!dataItemDone)
            {
                if (!tokenizer.HasCurrent())
                {
                    onIssue(new PkgdefIssue(PkgdefToken.GetStartIndex(tokens), PkgdefToken.GetLength(tokens), "Missing registry key data item equals sign ('=')."));
                    dataItemDone = true;
                }
                else
                {
                    while (tokenizer.HasCurrent())
                    {
                        PkgdefTokenType tokenType = tokenizer.GetCurrent().GetTokenType();
                        if (tokenType == PkgdefTokenType.NewLine)
                        {
                            onIssue(new PkgdefIssue(PkgdefToken.GetStartIndex(tokens), PkgdefToken.GetLength(tokens), "Missing registry key data item equals sign ('=')."));
                            dataItemDone = true;
                            break;
                        }
                        else
                        {
                            PkgdefToken token = tokenizer.TakeCurrent();
                            tokens.Add(token);
                            if (token.GetTokenType() == PkgdefTokenType.EqualsSign)
                            {
                                break;
                            }
                            else if (token.GetTokenType() != PkgdefTokenType.Whitespace)
                            {
                                onIssue(new PkgdefIssue(token.GetStartIndex(), token.GetLength(), "Expected registry key data item equals sign ('=')."));
                            }
                        }
                    }
                }
            }

            if (!dataItemDone)
            {
                if (!tokenizer.HasCurrent())
                {
                    onIssue(new PkgdefIssue(PkgdefToken.GetStartIndex(tokens), PkgdefToken.GetLength(tokens), "Missing registry key data item value."));
                }
                else
                {
                    int dataItemValueTokenCount = 0;
                    while (tokenizer.HasCurrent())
                    {
                        PkgdefTokenType tokenType = tokenizer.GetCurrent().GetTokenType();
                        if (tokenType == PkgdefTokenType.NewLine)
                        {
                            if (dataItemValueTokenCount == 0)
                            {
                                onIssue(new PkgdefIssue(PkgdefToken.GetStartIndex(tokens), PkgdefToken.GetLength(tokens), "Missing registry key data item value."));
                            }
                            break;
                        }
                        else
                        {
                            PkgdefToken token = tokenizer.TakeCurrent();
                            tokens.Add(token);
                            if (token.GetTokenType() != PkgdefTokenType.Whitespace)
                            {
                                dataItemValueTokenCount++;
                            }
                        }
                    }
                }
            }

            return(new PkgdefRegistryKeyDataItemSegment(tokens));
        }