Esempio n. 1
0
        public void BeAtTheEnd(int[] elements)
        {
            // Arrange
            var cursor = new ElementsCursor <int>(elements, 0);

            // Assert
            for (int i = 0; i < elements.Length; i++)
            {
                Assert.True(!cursor.IsAtTheEnd());
                cursor.MoveNext();
            }

            Assert.True(cursor.IsAtTheEnd());
        }
Esempio n. 2
0
 private static void ValidateArgumentEnd(ElementsCursor <char> cursor)
 {
     if (cursor.IsAtTheEnd())
     {
         throw new FormatException($"Missing closing bracket at symbol {cursor.Position}.");
     }
 }
Esempio n. 3
0
        public MessageTemplate Parse(string messageTemplate)
        {
            if (messageTemplate == null)
            {
                throw new ArgumentNullException(nameof(messageTemplate));
            }
            if (messageTemplate.Length == 0)
            {
                return(new MessageTemplate(Array.Empty <MessageTemplate.Token>()));
            }

            var chars  = new CharsReadOnlyList(messageTemplate);
            var cursor = new ElementsCursor <char>(chars, EndOfInput);
            var tokens = new List <MessageTemplate.Token>();

            while (!cursor.IsAtTheEnd())
            {
                switch (cursor.Peek())
                {
                case '{':
                    if (cursor.Peek(1) == '{')
                    {
                        // Escaped opening bracket
                        tokens.Add(ScanTextToken(cursor));
                    }
                    else
                    {
                        // Argument
                        tokens.Add(ScanArgumentToken(messageTemplate, cursor));
                    }
                    break;

                case '}':
                    if (cursor.Peek(1) == '}')
                    {
                        // Escaped closing bracket
                        tokens.Add(ScanTextToken(cursor));
                    }
                    else
                    {
                        throw new FormatException($"Unescaped closing bracket at symbol {cursor.Position}.");
                    }
                    break;

                default:
                    tokens.Add(ScanTextToken(cursor));
                    break;
                }
            }

            return(new MessageTemplate(tokens.ToArray()));
        }
Esempio n. 4
0
        private MessageTemplate.TextToken ScanTextToken(ElementsCursor <char> cursor)
        {
            var text = new StringBuilder(128);

            while (!cursor.IsAtTheEnd())
            {
                char c = cursor.Peek();
                if (c == '{')
                {
                    if (cursor.Peek(1) == '{')
                    {
                        // Escaped opening bracket
                        text.Append(c);
                        cursor.MoveNext(2);
                    }
                    else
                    {
                        // Beginning of an argument
                        break;
                    }
                }
                else if (c == '}')
                {
                    if (cursor.Peek(1) == '}')
                    {
                        // Escaped closing bracket
                        text.Append(c);
                        cursor.MoveNext(2);
                    }
                    else
                    {
                        // Unescaped closing bracket
                        // Error handled in the top method
                        break;
                    }
                }
                else
                {
                    text.Append(c);
                    cursor.MoveNext();
                }
            }

            return(new MessageTemplate.TextToken(text.ToString()));
        }
Esempio n. 5
0
        private SyntaxTrivia ScanWhitespaceTrivia(string input, ElementsCursor <char> cursor)
        {
            int start = cursor.Position;

            while (!cursor.IsAtTheEnd())
            {
                var c = cursor.Peek();
                if (!Char.IsWhiteSpace(c))
                {
                    break;
                }
                cursor.MoveNext();
            }
            if (cursor.Position == start)
            {
                return(null);
            }
            return(_syntaxFactory.WhitespaceTrivia(input, start, cursor.Position - start));
        }
Esempio n. 6
0
        private void ScanLiteralOrIdentifierToken(
            SyntaxTokenBuilder builder, string input, ElementsCursor <char> cursor)
        {
            int  start       = cursor.Position;
            char?quote       = null;
            var  stringValue = new StringBuilder(128);

            char first        = cursor.Peek();
            bool isIdentifier = Char.IsLetter(first);

            if (first == '"' || first == '\'')
            {
                quote        = first;
                isIdentifier = false;
                cursor.MoveNext();
            }

            while (!cursor.IsAtTheEnd())
            {
                char c = cursor.Peek();

                if (Char.IsWhiteSpace(c))
                {
                    if (!quote.HasValue)
                    {
                        break;
                    }
                    stringValue.Append(c);
                    cursor.MoveNext();
                }
                else if (c == '=' || c == ':')
                {
                    if (isIdentifier)
                    {
                        break;
                    }
                    stringValue.Append(c);
                    cursor.MoveNext();
                }
                else if (c == '"' || c == '\'')
                {
                    // Start of another quoted literal.
                    if (!quote.HasValue)
                    {
                        break;
                    }

                    if (c == quote)
                    {
                        char next = cursor.Peek(1);
                        if (next == c)
                        {
                            // Escaped quote sequence.
                            stringValue.Append(c);
                            cursor.MoveNext(2);
                        }
                        else
                        {
                            // Closing quote symbol.
                            cursor.MoveNext();
                            break;
                        }
                    }
                    else
                    {
                        // Another quote symbol.
                        stringValue.Append(c);
                        cursor.MoveNext();
                    }
                }
                else
                {
                    if (isIdentifier && !IsIdentifierSymbol(c))
                    {
                        isIdentifier = false;
                    }
                    stringValue.Append(c);
                    cursor.MoveNext();
                }
            }

            // We don't know for sure that this is a pure identifier without a context
            // but we definitely can identify a pure literal.
            if (isIdentifier)
            {
                _syntaxFactory.IdentifierOrLiteralToken(builder, input,
                                                        start, cursor.Position - start, stringValue.ToString());
            }
            else
            {
                _syntaxFactory.LiteralToken(builder, input,
                                            start, cursor.Position - start, stringValue.ToString(), quoted: quote.HasValue);
            }
        }
Esempio n. 7
0
 private bool HasMoreTokens(ElementsCursor <SyntaxToken> cursor)
 {
     return(!cursor.IsAtTheEnd() && cursor.Peek().Kind != cursor.TerminalElement.Kind);
 }