Bridge++  Ver. 1.3.x
evalexpr.cpp
Go to the documentation of this file.
1 
14 #include "evalexpr.h"
15 
16 //====================================================================
17 // global symbol entries
18 namespace {
19  struct _init_function
20  {
21  char const *name;
22  function_t func;
23  };
24 
25  struct _init_variable
26  {
27  char const *name;
28  double val;
29  };
30 }
31 
32 // import global symbol definitions
33 #include "evalexpr_global.h"
34 
35 // register global symbols
36 namespace {
37  SymbolTable init_global_symbol()
38  {
39  SymbolTable table;
40 
41  for (int i = 0; arithmetic_functions[i].name != 0; ++i) {
42  table.put_symbol(arithmetic_functions[i].name, arithmetic_functions[i].func);
43  }
44 
45  for (int i = 0; predefined_constants[i].name != 0; ++i) {
46  table.put_symbol(predefined_constants[i].name, predefined_constants[i].val);
47  }
48 
49  return table;
50  }
51 }
52 
53 SymbolTable EvalExpr::global_symbol_table = init_global_symbol();
54 
55 //====================================================================
56 // lexer interface for parser
57 int yylex(EvalExpr::semantic_type *yylval, EvalExpr& driver)
58 {
59  return driver.next_token(*yylval);
60 }
61 
62 
63 //====================================================================
65 {
66  if (m_trace) vout.paranoiac("%s: pos = %d, length = %zu\n", __func__, m_pos, m_src.length());
67 
68  char *p = const_cast<char *>(m_src.c_str()) + m_pos;
69 
70  int c = *p;
71 
72  // skip spaces
73  while ((c == ' ') || (c == '\t'))
74  {
75  c = *++p;
76  ++m_pos;
77  }
78 
79  if (c == '\0') return 0;
80 
81  if (c == '\n') return token::EOL;
82 
83  // find number [0-9](.[0-9]*)(e[+-]?[0-9]+)
84  if (isdigit(c)) {
85  enum
86  {
87  IN_INT, IN_FRAC, IN_EXP, IN_EXP_DIGIT
88  }
89  state = IN_INT;
90 
91  int i;
92  for (i = 0; ; c = p[++i]) {
93  if (state == IN_INT) {
94  if (isdigit(c)) {
95  } else if (c == '.') {
96  state = IN_FRAC;
97  } else if (c == 'e') {
98  state = IN_EXP;
99  } else {
100  break; // accept
101  }
102  } else if (state == IN_FRAC) {
103  if (isdigit(c)) {
104  } else if (c == 'e') {
105  state = IN_EXP;
106  } else {
107  break; // accept
108  }
109  } else if ((state == IN_EXP) || (state == IN_EXP_DIGIT)) {
110  if (isdigit(c)) {
111  } else if ((state == IN_EXP) && ((c == '+') || (c == '-'))) {
112  state = IN_EXP_DIGIT;
113  } else {
114  break; // accept
115  }
116  } else {
117  exit(EXIT_FAILURE);
118  }
119  }
120 
121  double x = atof(p);
122 
123 #ifdef __PGI
124  char *symbol = strdup(p);
125 #else
126  char *symbol = strndup(p, i + 1);
127 #endif
128  symbol[i] = '\0';
129 
130  if (m_trace) vout.paranoiac("%s: accept: number: \"%s\"(%d), %f\n", __func__, symbol, i, x);
131 
132  free(symbol);
133 
134  yylval.val = x;
135  m_pos += i;
136 
137  return token::NUMBER;
138  }
139 
140  // find identifier [a-zA-Z]([.a-zA-Z0-9]*)
141  if (isalpha(c)) {
142  int i;
143  for (i = 0; isalnum(p[i]) || p[i] == '.'; ++i) {
144  continue;
145  }
146 
147 #ifdef __PGI
148  char *symbol = strdup(p);
149 #else
150  char *symbol = strndup(p, i + 1);
151 #endif
152  symbol[i] = '\0';
153 
154  if (m_trace) vout.paranoiac("%s: accept: identifier: \"%s\" (%d)\n", __func__, symbol, i);
155 
156  yylval.sym = symbol;
157  m_pos += i;
158 
159  return token::IDENTIFIER;
160  }
161 
162  ++m_pos;
163 
164  return c;
165 }
166 
167 
168 //====================================================================
169 #if 0
170 bool EvalExpr::parse(double& result)
171 {
172  yy::parser parser(*this);
173 
174  parser.set_debug_level(m_trace);
175 
176  int retv = parser.parse(); // returns 0 if successful.
177 
178  if (retv == 0) {
179  if (m_trace) vout.paranoiac("%s: accept, result = %f\n", __func__, m_result);
180  result = m_result;
181  } else {
182  if (m_trace) vout.paranoiac("%s: reject\n", __func__);
183  result = double();
184  }
185 
186  return retv == 0;
187 }
188 #endif
189 
190 //====================================================================
192 {
193  yy::parser parser(*this);
194 
195  parser.set_debug_level(m_trace);
196 
197  int retv = parser.parse(); // returns 0 if successful.
198 
199  if (retv == 0) {
200  if (m_trace) vout.paranoiac("%s: accept, result = %f\n", __func__, m_result);
201  return m_result;
202  } else {
203  if (m_trace) vout.paranoiac("%s: reject\n", __func__);
204  return double(); // should throw exception or abort.
205  }
206 }
207 
208 
209 //====================================================================
210 void EvalExpr::set_result(double result)
211 {
212  if (m_trace) vout.paranoiac("%s: result = %f\n", __func__, result);
213 
214  m_result = result;
215 }
216 
217 
218 //====================================================================
219 double EvalExpr::get_symbol_value(char const *name)
220 {
222 }
223 
224 
225 //====================================================================
227 {
229 }
230 
231 
232 //====================================================================
233 void EvalExpr::error(const std::string& msg)
234 {
235  vout.general("EvalExpr: %s\n", msg.c_str());
236 }
237 
238 
239 //====================================================================
240 //============================================================END=====
function_t get_symbol_function(const std::string &name) const
bool put_symbol(const std::string &name, const double value)
BridgeIO vout
Definition: bridgeIO.cpp:278
void error(const std::string &msg)
Definition: evalexpr.cpp:233
double get_symbol_value(const std::string &name) const
function_t get_symbol_function(char const *name)
Definition: evalexpr.cpp:226
void general(const char *format,...)
Definition: bridgeIO.cpp:65
virtual int parse()
double parse()
Definition: evalexpr.cpp:191
static SymbolTable global_symbol_table
Definition: evalexpr.h:74
int yylex(EvalExpr::semantic_type *yylval, EvalExpr &driver)
Definition: evalexpr.cpp:57
unsigned int m_pos
Definition: evalexpr.h:69
bool m_trace
Definition: evalexpr.h:72
void set_debug_level(debug_level_type l)
Set the current debugging level.
Symbol semantic values.
EvalExpr class for algebraic expression in parameter strings.
Definition: evalexpr.h:39
void paranoiac(const char *format,...)
Definition: bridgeIO.cpp:99
double m_result
Definition: evalexpr.h:70
double get_symbol_value(char const *name)
Definition: evalexpr.cpp:219
void set_result(double result)
Definition: evalexpr.cpp:210
A Bison parser.
int next_token(semantic_type &yylval)
Definition: evalexpr.cpp:64
const std::string m_src
Definition: evalexpr.h:68
double(* function_t)(double)