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::BEGIN_LIST)
80  {
81  // Parenthesis. Evaluate the sub-units and multiply.
82  result.reset
83  (
84  result*parseNoBegin(nextPrior, tis, identity, table)
85  );
86 
87  // Check that the parentheses end
88  token t = tis.nextToken();
89  if (!t.isPunctuation() || t.pToken() != token::END_LIST)
90  {
91  FatalIOErrorInFunction(tis.stream())
92  << "Illegal token " << t << exit(FatalIOError);
93  }
94 
95  haveReadSymbol = true;
96  }
97  else if (nextToken.pToken() == token::END_LIST)
98  {
99  // End the sub-units
100  tis.putBack(nextToken);
101  return result;
102  }
103  else if (nextToken.pToken() == token::MULTIPLY)
104  {
105  // Multiply operator
106  if (nextPrior > lastPrior)
107  {
108  // This has priority. Evaluate the next units and multiply.
109  result.reset
110  (
111  result*parseNoBegin(nextPrior, tis, identity, table)
112  );
113  }
114  else
115  {
116  // Restore the token
117  tis.putBack(nextToken);
118  return result;
119  }
120 
121  haveReadSymbol = false;
122  }
123  else if (nextToken.pToken() == token::DIVIDE)
124  {
125  // Divide operator. As above.
126  if (nextPrior > lastPrior)
127  {
128  result.reset
129  (
130  result/parseNoBegin(nextPrior, tis, identity, table)
131  );
132  }
133  else
134  {
135  tis.putBack(nextToken);
136  return result;
137  }
138 
139  haveReadSymbol = false;
140  }
141  else if (nextToken.pToken() == '^')
142  {
143  // Power operator
144  if (nextPrior > lastPrior)
145  {
146  token t = tis.nextToken();
147  if (!t.isScalar())
148  {
149  FatalIOErrorInFunction(tis.stream())
150  << "Invalid power " << t << exit(FatalIOError);
151  }
152  result.reset(pow(result, t.scalarToken()));
153  }
154  else
155  {
156  tis.putBack(nextToken);
157  return result;
158  }
159 
160  haveReadSymbol = true;
161  }
162  else
163  {
164  FatalIOErrorInFunction(tis.stream())
165  << "Illegal token " << nextToken << exit(FatalIOError);
166  }
167  }
168  else
169  {
170  FatalIOErrorInFunction(tis.stream())
171  << "Illegal token " << nextToken << exit(FatalIOError);
172  }
173 
174  if (!tis.hasToken())
175  {
176  break;
177  }
178 
179  nextToken = tis.nextToken();
180  if (nextToken.error())
181  {
182  break;
183  }
184 
185  if (haveReadSymbol && (nextToken.isWord() || nextToken.isNumber()))
186  {
187  // Consecutive symbols are multiplied
188  tis.putBack(nextToken);
189  nextToken = token(token::MULTIPLY);
190  }
191  }
192 
193  return result;
194 }
195 
196 
197 template<class Type>
199 (
200  Istream& is,
201  const Type& identity,
202  const HashTable<Type>& table
203 )
204 {
205  symbols::tokeniser tis(is);
206 
207  return parseNoBegin(0, tis, identity, table);
208 }
209 
210 
211 // ************************************************************************* //
static label priority(const token &t)
...
Definition: symbols.C:192
@ 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 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
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
IOerror FatalIOError