Пример #1
0
        public static char Expect(this ISequence <char> cs, char expected)
        {
            var c = cs.GetNext();

            if (c != expected)
            {
                throw TokenizingException.UnexpectedCharacter(expected, c, cs.CurrentLocation);
            }
            return(c);
        }
Пример #2
0
        public IResult <Token> Parse(ParseState <char> state)
        {
            var input = state.Input;
            // Attempt to read through an arbitrary c# code literal. We can largely do this by
            // counting braces, but we have to get a bit more involved when we deal with
            // braces which are quoted as chars and strings: '{' and "{".

            // C# is a complicated language and this parser does not want to be complicated. It is expected
            // that the verbatim contents of this block are passed, opaquely, to roslyn for compilation.
            // This parser will not attempt in any way to recognize the contents of the C# block or provide
            // helpful diagnostics/recovery. If the user doesn't balance their {} brackets, they're going
            // to get an exception and a hard stop.
            var startConsumed = input.Consumed;
            var a             = input.GetNext();
            var b             = input.Peek();

            if (a != 'c' || b != '#')
            {
                input.PutBack(a);
                return(state.Fail(this, ""));
            }

            input.GetNext();

            while (char.IsWhiteSpace(input.Peek()))
            {
                input.GetNext();
            }
            input.Expect('{');
            int braceCount = 1;
            var buffer     = new List <char>();

            while (true)
            {
                var c = input.GetNext();
                if (c == '\0')
                {
                    TokenizingException.UnexpectedEndOfInput(input.CurrentLocation);
                }
                if (c == '\'')
                {
                    buffer.Add(c);
                    c = input.GetNext();
                    buffer.Add(c);
                    if (c == '\\')
                    {
                        c = input.GetNext();
                        buffer.Add(c);
                        c = input.GetNext();
                        while (c != '\'')
                        {
                            buffer.Add(c);
                            c = input.GetNext();
                        }
                    }
                    else
                    {
                        c = input.Expect('\'');
                    }
                    buffer.Add(c);
                    continue;
                }
                if (c == '"')
                {
                    buffer.Add(c);
                    while (true)
                    {
                        c = input.GetNext();
                        if (c == '\0')
                        {
                            TokenizingException.UnexpectedEndOfInput(input.CurrentLocation);
                        }
                        if (c == '"')
                        {
                            break;
                        }
                        if (c == '\\')
                        {
                            buffer.Add(c);
                            c = input.GetNext();
                        }
                        buffer.Add(c);
                    }
                    buffer.Add(c);
                    continue;
                }
                if (c == '@' && input.Peek() == '"')
                {
                    buffer.Add(c);
                    buffer.Add(input.GetNext());
                    while (true)
                    {
                        c = input.GetNext();
                        if (c == '\0')
                        {
                            TokenizingException.UnexpectedEndOfInput(input.CurrentLocation);
                        }
                        if (c == '"')
                        {
                            if (input.Peek() != '"')
                            {
                                break;
                            }
                            buffer.Add(c);
                            c = input.GetNext();
                        }

                        buffer.Add(c);
                    }
                    buffer.Add(c);
                    continue;
                }

                if (c == '{')
                {
                    braceCount++;
                    buffer.Add(c);
                    continue;
                }

                if (c == '}')
                {
                    braceCount--;
                    if (braceCount == 0)
                    {
                        break;
                    }
                    buffer.Add(c);
                    continue;
                }

                buffer.Add(c);
            }

            //_chars.Expect('}');
            return(state.Success(this, Token.CSharpLiteral(new string(buffer.ToArray())), input.Consumed - startConsumed, input.CurrentLocation));
        }