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