TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
StringTokenizer.cpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <StringTokenizer.h>
17#include <Char_ptr.h>
18#include <Objet_U.h>
19#include <math.h>
20#include <string.h>
21#include <sstream>
22#include <algorithm>
23
24//using namespace std;
25using std::stringstream;
26
27const int StringTokenizer::NUMBER=-2;
28const int StringTokenizer::STRING=-3;
29const int StringTokenizer::EOS=-1;
30
31
32// Operator identifiers are defined only once, shared between the Parser and StringTokenizer classes.
33// They are placed here and removed from the Parser class; they could be moved to a dedicated class if clearer.
34/* Note: the following constants must be greater than 0 to avoid conflicts with unary function identifiers.
35 */
36const int StringTokenizer::ADD = 0;
37const int StringTokenizer::SUBTRACT = 1;
38const int StringTokenizer::MULTIPLY = 2;
39const int StringTokenizer::DIVIDE = 3;
40const int StringTokenizer::POWER = 4;
41const int StringTokenizer::LT = 5;
42const int StringTokenizer::GT = 6;
43const int StringTokenizer::LE = 7;
44const int StringTokenizer::GE = 8;
45const int StringTokenizer::MOD = 9;
46const int StringTokenizer::MAX = 10;
47const int StringTokenizer::MIN = 11;
48const int StringTokenizer::AND = 12;
49const int StringTokenizer::OR = 13;
50const int StringTokenizer::EQ = 14;
51const int StringTokenizer::NEQ = 15;
52// Parentheses:
53const int StringTokenizer::GRP = 1000;
54const int StringTokenizer::ENDGRP = 1001;
55
56
57// Number of operators and keywords (parentheses "(" and ")" are not included).
58// The order of operators below must match the values of the static constants ADD, SUB, etc. defined above.
59//
60const int StringTokenizer::nb_op=16;
61const int StringTokenizer::nb_op_bis=11;
62const char StringTokenizer::keyword_op[][10] = { "ADD", "SUB", "MUL", "DIV" , "POW", "LT", "GT", "LE", "GE", "MOD", "MAX", "MIN", "AND", "OR", "EQ", "NEQ" };
63const char StringTokenizer::keyword_op_bis[][10] = { "+", "-", "*", "/", "^", "<", ">", "[", "]", "%", "$" };
64
65
67{
68 str = std::string("0");
69 init_keyword_op();
70 reste = &str[0];
71}
72
74{
75 str = s;
76 init_keyword_op();
77 reste = &str[0];
78}
79
80StringTokenizer::StringTokenizer(std::string s, std::string sep)
81{
82 str = s;
83 init_keyword_op();
84 reste = &str[0];
85}
86
88{
89
90 for (int i=0; i<StringTokenizer::nb_op; i++)
91 {
92 delete[] op_sep[i];
93 }
94 delete[] op_sep;
95
96}
97
98
99
101{
102 const char* ch = str.c_str();
103 int nb_o=0;
104 int nb_f=0;
105 int sz = (int)strlen(ch);
106 for (int i=0; i<sz; i++)
107 {
108 if (*(ch+i)=='(')
109 nb_o++;
110 else if (*(ch+i)==')')
111 nb_f++;
112 }
113 return (nb_o==nb_f);
114}
115
116
118{
119 char *tmp;
120 int type_sep, length;
121 tmp=find_sep(reste, type_sep, length);
122 if (tmp == nullptr)
123 {
124 //Cout << "Fin ? " << reste << finl;
125 if (reste[0] == '\0')
126 {
127 type = EOS;
128 }
129 else
130 {
131 if ( ((reste[0] >= '0') && ( reste[0] <= '9')) || (reste[0] == '.') )
132 {
133 // Added by OC to raise an error when input is like "2x"
134 int ind=(int)strlen(reste)-1;
135 if ( ((reste[ind] < '0') || (reste[ind] > '9')) && (reste[ind] != '.') )
136 {
137 Cerr << "The syntax " << reste << " is not allowed." << finl;
139 }
140 type = NUMBER;
141 stringstream stream;
142 stream << reste ;
143 stream >> nval;
144 if (!stream.eof() )
145 {
146 Cerr<<"Error conversion "<<reste<<" in number"<<finl;
148 }
149 }
150 else
151 {
152 type=STRING;
153 sval = reste;
154 std::transform(sval.begin(), sval.end(), sval.begin(), ::toupper);
155 }
156 while ((*reste++) != '\0') ;
157 reste--;
158 }
159 }
160 else if (tmp==reste)
161 {
162 type = type_sep;
163 reste=reste+length;
164 }
165 else
166 {
167 Char_ptr token;
168 token.allocate((int)(tmp-reste));
169
170 char* tok = token.getChar();;
171 int j=0;
172 for (int i=0; i<tmp-reste; i++)
173 {
174 if ( reste[i] != ' ' ) tok[j++] = reste[i];
175 }
176 tok[j] = '\0';
177 if (((tok[0] >= '0') && ( tok[0] <= '9')) || (tok[0] == '.') )
178 {
179 int ind;
180 double nval_tmp;
181
182 type = NUMBER;
183 stringstream stream;
184 ind = (int)(tmp-reste-1l);
185 reste = tmp;
186 if (tok[ind] == 'e' || tok[ind] == 'E' )
187 {
188 tok[ind]=' ';
189 stream << tok ;
190 stream >> nval_tmp;
191 char c;
192 stream >> c;
193
194 if (!stream.eof() )
195 {
196 Cerr<<"Error conversion "<<tok<<" in number"<<finl;
198 }
199 nextToken();
200 if (type == SUBTRACT)
201 {
202 nextToken();
203 if (type != NUMBER)
204 {
205 Cerr << "Error while interpreting the string " << str << finl;
207 }
208 nval_tmp*=pow(10,-nval);
209 }
210 else if (type == ADD)
211 {
212 nextToken();
213 if (type != NUMBER)
214 {
215 Cerr << "Error while interpreting the string " << str << finl;
217 }
218 nval_tmp*=pow(10.,nval);
219 }
220 else if (type == NUMBER)
221 {
222 // GF: depending on the version, the exponent is either parsed as below
223 nval_tmp*=pow(10.,nval);
224 // or as:
225 //nval_tmp = nval;
226 // Disallowed for now:
227 //Cerr << "Possible error while interpreting the string " << str << finl;
228 //Process::exit();
229 }
230 else
231 {
232 Cerr << "Error while interpreting the string " << str << finl;
234 }
235 }
236 else if ( ((tok[ind] < '0') || (tok[ind] > '9')) && (tok[ind] != '.') )
237 {
238 Cerr << " The syntax " << tok << " is not allowed." << finl;
240 throw;
241 }
242 else
243 {
244 stream << tok ;
245 stream >> nval_tmp;
246 if (!stream.eof() )
247 {
248
249 Cerr<<"Error conversion "<<tok<<" in number"<<finl;
251 }
252 }
253 nval = nval_tmp;
254 }
255 else
256 {
257 type=STRING;
258 sval = tok;
259 std::transform(sval.begin(), sval.end(), sval.begin(), ::toupper);
260 reste=tmp;
261 }
262 // delete[] tok;
263 }
264 return type;
265}
266
267
268
269// Private methods:
270
271void StringTokenizer::init_keyword_op()
272{
273 op_sep = new char*[nb_op];
274 // Each operator keyword is surrounded by "_":
275 // LT => _LT_ etc...
276 for (int i=0; i<nb_op; i++)
277 {
278 const char* blanc="_";
279 op_sep[i] = new char[strlen(keyword_op[i])+3];
280 strcpy(op_sep[i],blanc);
281 strcat(op_sep[i], keyword_op[i]);
282 strcat(op_sep[i], blanc);
283 }
284}
285
286
287/**
288 * Searches the string "ch" for the next occurrence of a separator.
289 * Returns the separator type ((, ), +, -, etc.) in the "type_sep" parameter.
290 * Also returns the length of the string corresponding to the separator found.
291 */
292char* StringTokenizer::find_sep(char* ch, int& type_sep, int& length)
293{
294 char * trouve=nullptr;
295 char * trouve_tmp;
296 type_sep=-1;
297 trouve_tmp = strstr(ch, "(");
298 int pos=100000;
299 if (trouve_tmp != nullptr)
300 {
301 pos = (int)(trouve_tmp-ch);
302 type_sep=GRP;
303 length=1;
304 trouve=trouve_tmp;
305 }
306 trouve_tmp = strstr(ch, ")");
307 if ((trouve_tmp != nullptr) && (trouve_tmp-ch<pos))
308 {
309 pos = (int)(trouve_tmp-ch);
310 type_sep=ENDGRP;
311 length=1;
312 trouve=trouve_tmp;
313 }
314 for (int i=0; i<StringTokenizer::nb_op; i++)
315 {
316 trouve_tmp = strstr(ch, op_sep[i]);
317 if ((trouve_tmp != nullptr) && (trouve_tmp-ch<pos))
318 {
319 pos = (int)(trouve_tmp-ch);
320 type_sep=i;
321 length=(int)strlen(op_sep[i]);
322 trouve=trouve_tmp;
323 }
324 }
325 for (int i=0; i<StringTokenizer::nb_op_bis; i++)
326 {
327 trouve_tmp = strstr(ch, keyword_op_bis[i]);
328 if ((trouve_tmp != nullptr) && ((int)(trouve_tmp-ch)<pos))
329 {
330 pos = (int)(trouve_tmp-ch);
331 type_sep=i;
332 length=(int)strlen(keyword_op_bis[i]);
333 trouve=trouve_tmp;
334 }
335 }
336
337 return trouve;
338}
339
340
341
342/*
343 int main()
344 {
345 //String s("23+34*12-13+COS ( 12 )* 2^3");
346 std::string s("2+3");
347 StringTokenizer tk(s);
348 Cout << StringTokenizer::NUMBER << finl;
349 Cout << StringTokenizer::EOS << finl;
350 Cout << StringTokenizer::STRING << finl;
351
352 while (tk.nextToken()!=StringTokenizer::EOS)
353 {
354 if (tk.type == StringTokenizer::STRING)
355 {
356 Cout << "String = " << tk.getSValue() << finl;
357 }
358 else if (tk.type == StringTokenizer::NUMBER)
359 {
360 Cout << "Value = " << tk.getNValue() << finl;
361 }
362 else
363 {
364 Cout << "Operator = " << (char) tk.type << finl;
365 }
366 }
367 }
368*/
class Char_ptr A character string to name TRUST objects.
Definition Char_ptr.h:28
void allocate(int n)
Definition Char_ptr.cpp:119
char * getChar()
Definition Char_ptr.h:39
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
static const int AND
static const int NUMBER
static const int EOS
static const int STRING
static const int MULTIPLY
static const int MIN
static const int GT
static const int POWER
static const int GRP
static const int GE
static const int LT
static const int LE
static const int MOD
static const int DIVIDE
static const int EQ
static const int ENDGRP
static const int SUBTRACT
static const int ADD
static const int OR
static const int MAX
static const int NEQ