symbolsTemplates.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2024 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "symbols.H"
27 
28 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
29 
30 template<class Type>
32 (
33  const label lastPrior,
34  tokeniser& tis,
35  const Type& identity,
36  const HashTable<Type>& table
37 )
38 {
39  Type result(identity);
40 
41  // Get initial token
42  token nextToken(tis.nextToken());
43 
44  // Store type of last token read. Used to detect two consecutive
45  // symbols and assume multiplication.
46  bool haveReadSymbol = false;
47 
48  while (true)
49  {
50  if (nextToken.isWord())
51  {
52  // Named unit conversion. Multiply.
53  result.reset(result*table[nextToken.wordToken()]);
54  haveReadSymbol = true;
55  }
56  else if (nextToken.isNumber())
57  {
58  // A number. This makes no sense.
59  FatalIOErrorInFunction(tis.stream())
60  << "Illegal token " << nextToken << exit(FatalIOError);
61  }
62  else if (nextToken.isPunctuation())
63  {
64  const label nextPrior = tokeniser::priority(nextToken);
65 
66  if (nextToken.pToken() == token::BEGIN_SQR)
67  {
68  // Start another set of symbols? This makes no sense.
69  FatalIOErrorInFunction(tis.stream())
70  << "Illegal token " << nextToken << exit(FatalIOError);
71  return result;
72  }
73  else if (nextToken.pToken() == token::END_SQR)
74  {
75  // End the units
76  tis.putBack(nextToken);
77  return result;
78  }
79  else if (nextToken.pToken() == token::COLON)
80  {
81  // End the units
82  tis.putBack(nextToken);
83  return result;
84  }
85  else if (nextToken.pToken() == token::BEGIN_LIST)
86  {
87  // Parenthesis. Evaluate the sub-units and multiply.
88  result.reset
89  (
90  result
91  *parseNoBegin(nextPrior, tis, identity, table)
92  );
93 
94  // Check that the parentheses end
95  token t = tis.nextToken();
96  if (!t.isPunctuation() || t.pToken() != token::END_LIST)
97  {
98  FatalIOErrorInFunction(tis.stream())
99  << "Illegal token " << t << exit(FatalIOError);
100  }
101 
102  haveReadSymbol = true;
103  }
104  else if (nextToken.pToken() == token::END_LIST)
105  {
106  // End the sub-units
107  tis.putBack(nextToken);
108  return result;
109  }
110  else if (nextToken.pToken() == token::MULTIPLY)
111  {
112  // Multiply operator
113  if (nextPrior > lastPrior)
114  {
115  // This has priority. Evaluate the next units and multiply.
116  result.reset
117  (
118  result
119  *parseNoBegin(nextPrior, tis, identity, table)
120  );
121  }
122  else
123  {
124  // Restore the token
125  tis.putBack(nextToken);
126  return result;
127  }
128 
129  haveReadSymbol = false;
130  }
131  else if (nextToken.pToken() == token::DIVIDE)
132  {
133  // Divide operator. As above.
134  if (nextPrior > lastPrior)
135  {
136  result.reset
137  (
138  result
139  /parseNoBegin(nextPrior, tis, identity, table)
140  );
141  }
142  else
143  {
144  tis.putBack(nextToken);
145  return result;
146  }
147 
148  haveReadSymbol = false;
149  }
150  else if (nextToken.pToken() == '^')
151  {
152  // Power operator
153  if (nextPrior > lastPrior)
154  {
155  token t = tis.nextToken();
156  if (!t.isScalar())
157  {
158  FatalIOErrorInFunction(tis.stream())
159  << "Invalid power " << t << exit(FatalIOError);
160  }
161  result.reset(pow(result, t.scalarToken()));
162  }
163  else
164  {
165  tis.putBack(nextToken);
166  return result;
167  }
168 
169  haveReadSymbol = true;
170  }
171  else
172  {
173  FatalIOErrorInFunction(tis.stream())
174  << "Illegal token " << nextToken << exit(FatalIOError);
175  }
176  }
177  else
178  {
179  FatalIOErrorInFunction(tis.stream())
180  << "Illegal token " << nextToken << exit(FatalIOError);
181  }
182 
183  if (!tis.hasToken())
184  {
185  break;
186  }
187 
188  nextToken = tis.nextToken();
189 
190  if (nextToken.error())
191  {
192  break;
193  }
194 
195  if (haveReadSymbol && (nextToken.isWord() || nextToken.isNumber()))
196  {
197  // Consecutive symbols are multiplied
198  tis.putBack(nextToken);
199  nextToken = token(token::MULTIPLY);
200  }
201  }
202 
203  return result;
204 }
205 
206 
207 template<class Type>
209 (
210  Istream& is,
211  const Type& identity,
212  const HashTable<Type>& table
213 )
214 {
215  symbols::tokeniser tis(is);
216 
217  Type result = parseNoBegin(0, tis, identity, table);
218 
219  is.putBack(tis.nextToken());
220 
221  return result;
222 }
223 
224 
225 // ************************************************************************* //
static label priority(const token &t)
...
Definition: symbols.C:194
@ DIVIDE
Definition: token.H:126
@ BEGIN_SQR
Definition: token.H:111
@ BEGIN_LIST
Definition: token.H:109
@ END_LIST
Definition: token.H:110
@ END_SQR
Definition: token.H:112
@ MULTIPLY
Definition: token.H:125
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:346
Type parseNoBeginOrEnd(Istream &is, const Type &identity, const HashTable< Type > &table)
Parse tokens into a dimension set or unit conversion, assuming that the '['.
Type parseNoBegin(const label lastPrior, tokeniser &tis, const Type &identity, const HashTable< Type > &table)
Parse tokens into a dimension set or unit conversion, assuming that the '['.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
void pow(LagrangianPatchField< typename powProduct< Type, r >::type > &f, const LagrangianPatchField< Type > &f1)
IOerror FatalIOError