summaryrefslogtreecommitdiff
path: root/src/binder/inc/stringlexer.hpp
blob: 257b883c51f66bf0fed76ca873fd453ffa4f2ad3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// ============================================================
//
// StringLexer.hpp
//


//
// Defines the StringLexer class
//
// ============================================================

#ifndef __BINDER__STRING_LEXER_HPP__
#define __BINDER__STRING_LEXER_HPP__

#include "bindertypes.hpp"

#define GO_IF_NOT_EXPECTED(expr, kRequiredLexemeType)   \
    if ((expr) != kRequiredLexemeType)                  \
    {                                                   \
        fIsValid = FALSE;                               \
        goto Exit;                                      \
    }

#define GO_IF_END_OR_NOT_EXPECTED(expr, kRequiredLexemeType)            \
    {                                                                   \
        LEXEME_TYPE kGotLexemeType = (expr);                            \
        if (kGotLexemeType == LEXEME_TYPE_END_OF_STREAM)                \
        {                                                               \
            goto Exit;                                                  \
        }                                                               \
        else                                                            \
        {                                                               \
            GO_IF_NOT_EXPECTED(kGotLexemeType, kRequiredLexemeType);    \
        }                                                               \
    }

namespace BINDER_SPACE
{
    class StringLexer
    {
    public:        
        typedef enum
        {
            LEXEME_TYPE_INVALID,
            LEXEME_TYPE_EQUALS,
            LEXEME_TYPE_COMMA,
            LEXEME_TYPE_COLON,
            LEXEME_TYPE_SEMICOLON,
            LEXEME_TYPE_STRING,
            LEXEME_TYPE_END_OF_STREAM
        } LEXEME_TYPE;

        inline StringLexer();
        inline ~StringLexer();

        inline void Init(SString &inputString, BOOL fSupportEscaping);

        static inline BOOL IsWhitespace(WCHAR wcChar);
        static inline BOOL IsEOS(WCHAR wcChar);
        static inline BOOL IsQuoteCharacter(WCHAR wcChar);

        virtual BOOL IsSeparatorChar(WCHAR wcChar) = NULL;
        virtual LEXEME_TYPE GetLexemeType(WCHAR wcChar) = NULL;

    protected:
        static const WCHAR INVALID_CHARACTER = -1;

        LEXEME_TYPE GetNextLexeme(SString &currentString, BOOL fPermitUnescapedQuotes = FALSE);

        inline WCHAR PopCharacter(BOOL *pfIsEscaped);
        inline void PushCharacter(WCHAR wcCurrentChar,
                                  BOOL fIsEscaped);

        inline WCHAR GetRawCharacter();
        inline void PushRawCharacter();
        inline WCHAR DecodeUTF16Character();
        inline WCHAR GetNextCharacter(BOOL *pfIsEscaped);

        inline WCHAR ParseUnicode();
        LEXEME_TYPE ParseString(SString &currentString,
                                BOOL     fPermitUnescapeQuotes);

        void TrimTrailingWhiteSpaces(SString &currentString);

        SString::Iterator m_cursor;
        SString::Iterator m_end;

        WCHAR m_wcCurrentChar;
        BOOL m_fCurrentCharIsEscaped;
        BOOL m_fSupportEscaping;
        BOOL m_fReadRawCharacter;
    };

#include "stringlexer.inl"
};

#endif