Пример #1
0
        protected void UnescapeSymbolValue()
        {
            Debug.Assert(CharSource[_startPosition] == '@' && CharSource[_startPosition + 1] == '@');
            if (SkipValueParsing)
            {
                return;
            }

            _value = _s;
            UString original = CharSource.Slice(_startPosition + 2, InputPosition - _startPosition - 2);

            if (_hasEscapes)
            {
                _textValue = Les3Lexer.UnescapeQuotedString(ref original, Error);
                Debug.Assert(original.IsEmpty);
            }
            else if (original[0, '\0'] == '`')
            {
                _textValue = original.Substring(1, original.Length - 2);
            }
            else
            {
                _textValue = original;
            }
        }
Пример #2
0
 protected UString UnescapeString(bool isTripleQuoted, bool allowExtraIndent = false)
 {
     if (SkipValueParsing)
     {
         return("");
     }
     if (_hasEscapes)
     {
         UString original = CharSource.Slice(_startPosition, InputPosition - _startPosition);
         _textValue = Les3Lexer.UnescapeQuotedString(ref original, Error, IndentString, allowExtraIndent);
         Debug.Assert(original.IsEmpty);
     }
     else
     {
         Debug.Assert(CharSource.TryGet(InputPosition - 1, '?') == CharSource.TryGet(_startPosition, '!'));
         if (isTripleQuoted)
         {
             _textValue = CharSource.Slice(_startPosition + 3, InputPosition - _startPosition - 6).ToString();
         }
         else
         {
             _textValue = CharSource.Slice(_startPosition + 1, InputPosition - _startPosition - 2).ToString();
         }
     }
     return(_textValue);
 }
Пример #3
0
        // After the generated lexer code determines the boundaries of the token,
        // one of these methods extracts the value of the token (e.g. "17L" => (long)17)
        // There are value parsers for identifiers, numbers, and strings; certain
        // parser cores are also accessible as public static methods.

        #region String unescaping (including public UnescapeQuotedString())

        protected void UnescapeSQStringValue()
        {
            _value = _c;
            var text = Text();

            if (!_hasEscapes)
            {
                _textValue = text.Slice(1, text.Length - 2);
            }
            else
            {
                _textValue = Les3Lexer.UnescapeQuotedString(ref text, Error);
            }
        }
Пример #4
0
        void Case(UString input, TokenType[] tokenTypes, params object[] expected)
        {
            Debug.Assert(expected.Length <= tokenTypes.Length);

            bool error = false;
            var  lexer = new Les3Lexer(input, "", new MessageSinkFromDelegate((type, ctx, msg, args) => {
                TraceMessageSink.Value.Write(type, ctx, msg, args); error = true;
            }));

            int index = 0;

            for (int i = 0; i < tokenTypes.Length; i++)
            {
                error = false;
                Token token = lexer.NextToken().Value;
                Assert.LessOrEqual(index, token.StartIndex);
                Assert.AreEqual(tokenTypes[i], token.Type());
                if (i < expected.Length)
                {
                    var value      = token.IsUninterpretedLiteral ? token.TextValue(lexer).ToString() : token.Value;
                    var expected_i = expected[i];
                    if (expected[i] is Error e)
                    {
                        Assert.IsTrue(error, "Expected error didn't occur in «{0}»", input);
                        expected_i = e.Value;
                    }
                    else
                    {
                        Assert.IsFalse(error, "Unexpected error in token [{0}] of «{1}»", i, input);
                    }
                    if (expected_i is Pair <string, Symbol> pair)
                    {
                        Assert.AreEqual(pair.A, value);
                        Assert.AreEqual(pair.B, token.TypeMarker);
                    }
                    else
                    {
                        Assert.AreEqual(expected_i, value);
                    }
                }
                index = token.EndIndex;
            }
            var nothing = lexer.NextToken();

            Assert.That(!nothing.HasValue, "Extra token after the expected ones in «" + input.ToString() + "»");
        }
Пример #5
0
        /// <summary>Parses an LES2-style identifier such as <c>foo</c>, <c>@foo</c>,
        /// <c>@`foo`</c> or <c>@--punctuation--</c>.
        /// </summary>
        /// <param name="source">Text to parse. On return, the range has been
        /// decreased by the length of the token; this method also stops if this
        /// range becomes empty.</param>
        /// <param name="onError">A method to call on error</param>
        /// <param name="checkForNamedLiteral">This is set to true when the input
        /// starts with @ but doesn't use backquotes, which could indicate that
        /// it is an LES named literal such as @false or @null.</param>
        /// <returns>The parsed version of the identifier.</returns>
        public static string ParseIdentifier(ref UString source, Action <int, string> onError, out bool checkForNamedLiteral)
        {
            checkForNamedLiteral = false;
            StringBuilder parsed = TempSB();

            UString start = source;
            bool    fail;
            int     c = source.PopFirst(out fail);

            if (c == '@')
            {
                // expecting: (BQString | Star(Set("[0-9a-zA-Z_'#~!%^&*-+=|<>/?:.@$]") | IdExtLetter))
                c = source.PopFirst(out fail);
                if (c == '`')
                {
                    Les3Lexer.UnescapeString(ref source, (char)c, false, onError, parsed);
                }
                else
                {
                    while (SpecialIdSet.Contains(c) || c >= 128 && char.IsLetter((char)c))
                    {
                        parsed.Append((char)c);
                        c = source.PopFirst(out fail);
                    }
                    checkForNamedLiteral = true;
                }
            }
            else if (IsIdStartChar(c))
            {
                parsed.Append(c);
                for (;;)
                {
                    c = source.PopFirst(out fail);
                    if (!IsIdContChar(c))
                    {
                        break;
                    }
                    parsed.Append((char)c);
                }
            }
            return(parsed.ToString());
        }
Пример #6
0
        protected internal static object ParseSQStringValue(UString text, Action <int, string> Error)
        {
            var sb = TempSB();

            Les3Lexer.UnescapeQuotedString(ref text, Error, sb, "\t");
            Debug.Assert(text.IsEmpty);
            if (sb.Length == 1)
            {
                return(CG.Cache(sb[0]));
            }
            else
            {
                if (sb.Length == 0)
                {
                    Error(0, Localize.Localized("Empty character literal"));
                }
                else
                {
                    Error(0, Localize.Localized("Character literal has {0} characters (there should be exactly one)", sb.Length));
                }
                return(sb.ToString());
            }
        }
Пример #7
0
        void Case(UString input, TokenType[] tokenTypes, params object[] expected)
        {
            Debug.Assert(expected.Length <= tokenTypes.Length);

            bool error = false;
            var  lexer = new Les3Lexer(input, "", new MessageSinkFromDelegate((type, ctx, msg, args) => {
                TraceMessageSink.Value.Write(type, ctx, msg, args); error = true;
            }));

            int index = 0;

            for (int i = 0; i < tokenTypes.Length; i++)
            {
                error = false;
                Token token = lexer.NextToken().Value;
                Assert.LessOrEqual(index, token.StartIndex);
                Assert.AreEqual(tokenTypes[i], token.Type());
                if (i < expected.Length)
                {
                    if (expected[i] is Error)
                    {
                        Assert.IsTrue(error, "Expected error didn't occur in «{0}»", input);
                        Assert.AreEqual(((Error)expected[i]).Value, token.Value);
                    }
                    else
                    {
                        Assert.AreEqual(expected[i], token.Value);
                        Assert.IsFalse(error, "Unexpected error in token [{0}] of «{1}»", i, input);
                    }
                }
                index = token.EndIndex;
            }
            var nothing = lexer.NextToken();

            Assert.That(!nothing.HasValue, "Extra token after the expected ones in «" + input.ToString() + "»");
        }
Пример #8
0
 public static bool UnescapeString(ref UString sourceText, char quoteType, bool isTripleQuoted, Action <int, string> onError, StringBuilder sb, UString indentation = default(UString), bool les3TQIndents = false) =>
 Les3Lexer.UnescapeString(ref sourceText, quoteType, isTripleQuoted, onError, sb, indentation, les3TQIndents);
Пример #9
0
 public static void UnescapeQuotedString(ref UString sourceText, Action <int, string> onError, StringBuilder sb, UString indentation = default(UString), bool les3TQIndents = false)
 => Les3Lexer.UnescapeQuotedString(ref sourceText, onError, sb, indentation, les3TQIndents);