Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/common/lexers/tokenstream.cpp
9912 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#include "tokenstream.h"
5
#include "../math/emath.h"
6
7
namespace embree
8
{
9
/* shorthands for common sets of characters */
10
const std::string TokenStream::alpha = "abcdefghijklmnopqrstuvwxyz";
11
const std::string TokenStream::ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
12
const std::string TokenStream::numbers = "0123456789";
13
const std::string TokenStream::separators = "\n\t\r ";
14
const std::string TokenStream::stringChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 _.,+-=:/*\\";
15
16
/* creates map for fast categorization of characters */
17
static void createCharMap(bool map[256], const std::string& chrs) {
18
for (size_t i=0; i<256; i++) map[i] = false;
19
for (size_t i=0; i<chrs.size(); i++) map[uint8_t(chrs[i])] = true;
20
}
21
22
/* build full tokenizer that takes list of valid characters and keywords */
23
TokenStream::TokenStream(const Ref<Stream<int> >& cin, //< stream to read from
24
const std::string& alpha, //< valid characters for identifiers
25
const std::string& seps, //< characters that act as separators
26
const std::vector<std::string>& symbols) //< symbols
27
: cin(cin), symbols(symbols)
28
{
29
createCharMap(isAlphaMap,alpha);
30
createCharMap(isSepMap,seps);
31
createCharMap(isStringCharMap,stringChars);
32
}
33
34
bool TokenStream::decDigits(std::string& str_o)
35
{
36
bool ok = false;
37
std::string str;
38
if (cin->peek() == '+' || cin->peek() == '-') str += (char)cin->get();
39
while (isDigit(cin->peek())) { ok = true; str += (char)cin->get(); }
40
if (ok) str_o += str;
41
else cin->unget(str.size());
42
return ok;
43
}
44
45
bool TokenStream::decDigits1(std::string& str_o)
46
{
47
bool ok = false;
48
std::string str;
49
while (isDigit(cin->peek())) { ok = true; str += (char)cin->get(); }
50
if (ok) str_o += str; else cin->unget(str.size());
51
return ok;
52
}
53
54
bool TokenStream::trySymbol(const std::string& symbol)
55
{
56
size_t pos = 0;
57
while (pos < symbol.size()) {
58
if (symbol[pos] != cin->peek()) { cin->unget(pos); return false; }
59
cin->drop(); pos++;
60
}
61
return true;
62
}
63
64
bool TokenStream::trySymbols(Token& token, const ParseLocation& loc)
65
{
66
for (size_t i=0; i<symbols.size(); i++) {
67
if (!trySymbol(symbols[i])) continue;
68
token = Token(symbols[i],Token::TY_SYMBOL,loc);
69
return true;
70
}
71
return false;
72
}
73
74
bool TokenStream::tryFloat(Token& token, const ParseLocation& loc)
75
{
76
bool ok = false;
77
std::string str;
78
if (trySymbol("nan")) {
79
token = Token(float(nan));
80
return true;
81
}
82
if (trySymbol("+inf")) {
83
token = Token(float(pos_inf));
84
return true;
85
}
86
if (trySymbol("-inf")) {
87
token = Token(float(neg_inf));
88
return true;
89
}
90
91
if (decDigits(str))
92
{
93
if (cin->peek() == '.') {
94
str += (char)cin->get();
95
decDigits(str);
96
if (cin->peek() == 'e' || cin->peek() == 'E') {
97
str += (char)cin->get();
98
if (decDigits(str)) ok = true; // 1.[2]E2
99
}
100
else ok = true; // 1.[2]
101
}
102
else if (cin->peek() == 'e' || cin->peek() == 'E') {
103
str += (char)cin->get();
104
if (decDigits(str)) ok = true; // 1E2
105
}
106
}
107
else
108
{
109
if (cin->peek() == '.') {
110
str += (char)cin->get();
111
if (decDigits(str)) {
112
if (cin->peek() == 'e' || cin->peek() == 'E') {
113
str += (char)cin->get();
114
if (decDigits(str)) ok = true; // .3E2
115
}
116
else ok = true; // .3
117
}
118
}
119
}
120
if (ok) {
121
token = Token((float)atof(str.c_str()),loc);
122
}
123
else cin->unget(str.size());
124
return ok;
125
}
126
127
bool TokenStream::tryInt(Token& token, const ParseLocation& loc) {
128
std::string str;
129
if (decDigits(str)) {
130
token = Token(atoi(str.c_str()),loc);
131
return true;
132
}
133
return false;
134
}
135
136
bool TokenStream::tryString(Token& token, const ParseLocation& loc)
137
{
138
std::string str;
139
if (cin->peek() != '\"') return false;
140
cin->drop();
141
while (cin->peek() != '\"') {
142
const int c = cin->get();
143
if (!isStringChar(c)) THROW_RUNTIME_ERROR("invalid string character "+std::string(1,c)+" at "+loc.str());
144
str += (char)c;
145
}
146
cin->drop();
147
token = Token(str,Token::TY_STRING,loc);
148
return true;
149
}
150
151
bool TokenStream::tryIdentifier(Token& token, const ParseLocation& loc)
152
{
153
std::string str;
154
if (!isAlpha(cin->peek())) return false;
155
str += (char)cin->get();
156
while (isAlphaNum(cin->peek())) str += (char)cin->get();
157
token = Token(str,Token::TY_IDENTIFIER,loc);
158
return true;
159
}
160
161
void TokenStream::skipSeparators()
162
{
163
/* skip separators */
164
while (cin->peek() != EOF && isSeparator(cin->peek()))
165
cin->drop();
166
}
167
168
Token TokenStream::next()
169
{
170
Token token;
171
skipSeparators();
172
ParseLocation loc = cin->loc();
173
if (trySymbols (token,loc)) return token; /**< try to parse a symbol */
174
if (tryFloat (token,loc)) return token; /**< try to parse float */
175
if (tryInt (token,loc)) return token; /**< try to parse integer */
176
if (tryString (token,loc)) return token; /**< try to parse string */
177
if (tryIdentifier(token,loc)) return token; /**< try to parse identifier */
178
if (cin->peek() == EOF ) return Token(loc); /**< return EOF token */
179
return Token((char)cin->get(),loc); /**< return invalid character token */
180
}
181
}
182
183