Exemplo n.º 1
0
        private LexResult LexString(string typeName)
        {
            Debug.Assert(Buffer.Peek(0) == '"' || Buffer.Peek(0) == '\'');
            char quoteChar = Buffer.Peek();

            Buffer.AdvanceColumn();
            bool         isComplete = false;
            CppTokenKind kind       = quoteChar == '\'' ? CppTokenKind.CharLiteral : CppTokenKind.StringLiteral;
            int          maxCount   = (kind == CppTokenKind.CharLiteral) ? 1 : -1;
            int          minCount   = (kind == CppTokenKind.CharLiteral) ? 1 : 0;
            int          count      = 0;

            while (!Buffer.IsEOF)
            {
                char first  = Buffer.Peek();
                char second = Buffer.Peek(1);
                if (first == quoteChar)
                {
                    isComplete = true;
                    break;
                }
                else if (first == '\\')
                {
                    switch (second)
                    {
                    case '\'':
                    case '"':
                    case '?':
                    case '\\':
                    case 'a':
                    case 'b':
                    case 'f':
                    case 'n':
                    case 'e':
                    case 'r':
                    case 't':
                    case 'v':
                    {
                        Buffer.AdvanceColumns(2);
                        ++count;
                        continue;
                    }

                    case 'x':
                    case 'X':
                    case 'u':
                    case 'U':
                    {
                        Buffer.AdvanceColumns(2);
                        if (SyntaxUtils.IsHex(Buffer.Peek()))
                        {
                            int len = 0;
                            while (!Buffer.IsEOF)
                            {
                                if (!SyntaxUtils.IsHex(Buffer.Peek()))
                                {
                                    break;
                                }
                                else
                                {
                                    ++len;
                                    Buffer.AdvanceColumn();
                                }
                            }
                        }
                        else
                        {
                            AddError(Buffer.TextPosition, $"Unsupported hex escape character '{Buffer.Peek()}'!", typeName);
                            break;
                        }
                        ++count;
                        continue;
                    }

                    default:
                        if (SyntaxUtils.IsOctal(second))
                        {
                            Buffer.AdvanceColumn();
                            while (!Buffer.IsEOF)
                            {
                                if (!SyntaxUtils.IsOctal(Buffer.Peek()))
                                {
                                    break;
                                }
                                else
                                {
                                    Buffer.AdvanceColumn();
                                }
                            }
                            ++count;
                            continue;
                        }
                        else
                        {
                            AddError(Buffer.TextPosition, $"Not supported escape character '{Buffer.Peek()}'!", typeName);
                            break;
                        }
                    }
                }
                else if (SyntaxUtils.IsLineBreak(first))
                {
                    break;
                }
                else if (char.IsWhiteSpace(first))
                {
                    Buffer.AdvanceManual(first, second);
                }
                else
                {
                    Buffer.AdvanceColumn();
                }
                ++count;
            }

            // Skip over quote char
            if (isComplete)
            {
                Debug.Assert(Buffer.Peek() == quoteChar);
                Buffer.AdvanceColumn();
            }

            if (!isComplete)
            {
                AddError(Buffer.LexemeStart, $"Unterminated {typeName} literal!", typeName);
            }
            else
            {
                if (minCount > 0 && count < minCount)
                {
                    AddError(Buffer.LexemeStart, $"Not enough characters for {typeName} literal, expect {minCount} but got {count}!", typeName);
                }
                else if (maxCount > -1 && (count > maxCount))
                {
                    AddError(Buffer.LexemeStart, $"Too many characters for {typeName} literal, expect {maxCount} but got {count}!", typeName);
                }
            }
            return(new LexResult(kind, isComplete));
        }