/
CxxLexing.cxx
152 lines (137 loc) · 3.69 KB
/
CxxLexing.cxx
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#ifdef FLEX_PP_CLASS
FLEX_PP_CLASS theLexer;
#define LEX_DOT theLexer .
#else
#define LEX_DOT
#endif
bool c_keywords = false;
bool echo_line_numbers = false;
bool echo_line_text = false;
size_t line_number = 0;
#ifdef NEEDS_YYWRAP
int yywrap() { return 1; }
#endif
CxxToken *yylex_token()
{
if (!LEX_DOT yylex())
return 0;
return yyToken;
}
//
// Configure the lexer to reflect successful parsing of a character value, assigning it to yylval.
//
// The source someText[aLength] should correspond to the parsed text including any L or ' prefix
// but excluding any ' suffix. In this way the return can indicate whether a wide character has
// been detected and the routine can accommodate a variety of erroneous terminations.
//
CxxToken *make_character(const char *someText, size_t aLength)
{
bool isWide = false;
if (someText && aLength)
{
if (*someText == 'L')
{
isWide = true;
someText++;
aLength--;
}
if (!aLength || (*someText != '\''))
ERRMSG("BUG - bad start of character literal.");
if (aLength)
{
someText++;
aLength--;
}
}
if (isWide)
return make_wide_character(someText, aLength);
else
return make_narrow_character(someText, aLength);
}
CxxToken *make_identifier(const char *someText, size_t aLength)
{
return new CxxNaffToken(PARSE_TOKEN(Identifier), someText, aLength);
}
//
// Buffer the incoming line, before any characters are analysed.
//
void make_line(const char *yyText, size_t yyLeng)
{
if (echo_line_text)
cout << tokenMarkDepth << ": " << line_number << ": " << yyText << flush;
else if (echo_line_numbers)
cout << line_number << endl;
line_number++ ;
}
CxxToken *make_literal_character(const char *someText, size_t aLength)
{
return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength);
}
CxxToken *make_narrow_character(const char *someText, size_t aLength)
{
return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength);
}
CxxToken *make_narrow_string(const char *someText, size_t aLength)
{
return new CxxNaffToken(PARSE_TOKEN(StringLiteral), someText, aLength);
}
CxxToken *make_number(const char *someText, size_t aLength)
{
return new CxxNaffToken(PARSE_TOKEN(IntegerLiteral), someText, aLength);
}
//
// Configure the lexer to reflect successful parsing of a categorised string.
//
// The source someText[aLength] should correspond to the parsed text including any
// L or " prefix but excluding any " suffix. In this way the return can indicate whether a wide
// character has been detected and the routine can accommodate a variety of erroneous terminations.
//
CxxToken *make_string(const char *someText, size_t aLength)
{
bool isWide = false;
if (someText && aLength)
{
if (*someText == 'L')
{
isWide = true;
someText++;
aLength--;
}
if (!aLength || (*someText != '"'))
ERRMSG("BUG - bad start of string literal.");
if (aLength)
{
someText++;
aLength--;
}
}
if (isWide)
return make_wide_string(someText, aLength);
else
return make_narrow_string(someText, aLength);
}
//
// Return the appropriate 1 of 256 flyweight tokens for the ASCII characters.
//
CxxToken *make_token(size_t tokenValue)
{
static CxxToken *asciiTokens[256];
if (tokenValue >= (sizeof(asciiTokens)/sizeof(asciiTokens[0])))
{
ERRMSG("Cannot make_token for " << tokenValue);
return 0;
}
CxxToken **p = &asciiTokens[tokenValue];
CxxToken *theToken = *p;
if (!theToken)
*p = theToken = new CxxToken(tokenValue);
return theToken;
}
CxxToken *make_wide_character(const char *someText, size_t aLength)
{
return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength);
}
CxxToken *make_wide_string(const char *someText, size_t aLength)
{
return new CxxNaffToken(PARSE_TOKEN(StringLiteral), someText, aLength);
}