OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
Expressions.cpp
Go to the documentation of this file.
1 // ------------------------------------------------------------------------
2 // $RCSfile: Expressions.cpp,v $
3 // ------------------------------------------------------------------------
4 // $Revision: 1.2.4.1 $
5 // ------------------------------------------------------------------------
6 // Copyright: see Copyright.readme
7 // ------------------------------------------------------------------------
8 //
9 // Namespace Expressions:
10 // This namespace contains the attribute parsers for OPAL:
11 // a collection of functions.
12 //
13 // ------------------------------------------------------------------------
14 //
15 // $Date: 2002/12/09 15:06:08 $
16 // $Author: jsberg $
17 //
18 // ------------------------------------------------------------------------
19 
25 #include "AbstractObjects/Table.h"
28 #include "Expressions/ABinary.h"
29 #include "Expressions/AColumn.h"
30 #include "Expressions/AList.h"
31 #include "Expressions/ARefExpr.h"
32 #include "Expressions/ARow.h"
33 #include "Expressions/ASUnary.h"
34 #include "Expressions/AUnary.h"
35 #include "Expressions/ATable.h"
36 #include "Expressions/Indexer.h"
37 #include "Expressions/SBinary.h"
38 #include "Expressions/SCell.h"
39 #include "Expressions/SConstant.h"
40 #include "Expressions/SFunction.h"
41 #include "Expressions/SHash.h"
42 #include "Expressions/SNull.h"
43 #include "Expressions/SRefAttr.h"
44 #include "Expressions/SRefExpr.h"
45 #include "Expressions/SUnary.h"
46 #include "Expressions/TFind.h"
47 #include "Expressions/TFunction0.h"
48 #include "Expressions/TFunction1.h"
49 #include "Expressions/TFunction2.h"
50 #include "Parser/Statement.h"
52 #include "Utilities/Options.h"
53 #include "Utilities/ParseError.h"
54 #include "Utilities/CLRangeError.h"
55 #include "Utilities/Round.h"
56 #include "Utilities/Truncate.h"
58 #include <algorithm>
59 #include <cassert>
60 #include <cerrno>
61 #include <cmath>
62 #include <list>
63 #include <sstream>
64 #include <vector>
65 
66 
67 // Namespace Expressions
68 // ------------------------------------------------------------------------
69 
70 namespace Expressions {
71 
72 
73  // Boolean operators.
74  // ----------------------------------------------------------------------
75 
76  bool Or(bool a, bool b) { return a || b; }
77  static const TFunction2<bool, bool> logOr = { "||", 1, Or };
78 
79  bool And(bool a, bool b) { return a && b; }
80  static const TFunction2<bool, bool> logAnd = { "&&", 2, And };
81 
82  bool Le(double a, double b) { return a <= b; }
83  static const TFunction2<bool, double> lessEqual = { "<=", 3, Le } ;
84 
85  bool Lt(double a, double b) { return a < b; }
86  static const TFunction2<bool, double> less = { "<", 3, Lt } ;
87 
88  bool Ge(double a, double b) { return a >= b; }
89  static const TFunction2<bool, double> greaterEqual = { ">=", 3, Ge } ;
90 
91  bool Gt(double a, double b) { return a > b; }
92  static const TFunction2<bool, double> greater = { ">", 3, Gt } ;
93 
94  bool Eq(double a, double b) { return a == b; }
95  static const TFunction2<bool, double> equal = { "==", 3, Eq } ;
96 
97  bool Ne(double a, double b) { return a != b; }
98  static const TFunction2<bool, double> notEqual = { "!=", 3, Ne } ;
99 
100  // Real operators with one or two operands.
101  // ----------------------------------------------------------------------
102 
103  double Neg(double a) {
104  return - a;
105  }
106 
107  static const TFunction1<double, double> negate = { "-", 5, Neg };
108 
109  double Sign(double a) {
110  return (a > 0.) ? 1. : (a < 0.) ? -1. : 0.;
111  }
112 
113  double Tgauss(double a) {
114  double x, y;
115  do { Options::rangen.gauss(x, y); }
116  while(std::abs(x) > a);
117  return x;
118  }
119 
120  double Add(double a, double b) {
121  return a + b;
122  }
123 
124  static const TFunction2<double, double> plus = { "+", 4, Add };
125 
126  double Sub(double a, double b) {
127  return a - b;
128  }
129 
130  static const TFunction2<double, double> minus = { "-", 4, Sub };
131 
132  double Mpy(double a, double b) {
133  return a * b;
134  }
135 
136  static TFunction2<double, double> times = { "*", 5, Mpy };
137 
138  double Div(double a, double b) {
139  if(b == 0.0) {
140  errno = EDOM;
141  return 1.0;
142  } else {
143  return a / b;
144  }
145  }
146 
147  static TFunction2<double, double> divide = { "/", 5, Div };
148 
149  // Real functions without arguments.
150  // ----------------------------------------------------------------------
151 
152 
153  double getEkin() {
154  auto p = OpalData::getInstance()->getPartBunch();
155  if (p)
156  return p->get_meanKineticEnergy();
157  else
158  return -1.0;
159  }
160 
161 
162  double ranf() {
163  return Options::rangen.uniform();
164  }
165 
166  double gauss() {
167  double x, y;
168  Options::rangen.gauss(x, y);
169  return x;
170  }
171 
172  static const TFunction0<double> table0[] = {
173  {"GETEKIN", -2, getEkin},
174  {"RANF", -2, ranf },
175  {"GAUSS", -2, gauss },
176  {"SI", -2, SFunction::arcIn },
177  {"SC", -2, SFunction::arcCtr },
178  {"SO", -2, SFunction::arcOut },
179  { 0, -1, 0 }
180  };
181 
182  // Real functions with two arguments.
183  // ----------------------------------------------------------------------
184 
185  static const TFunction1<double, double> table1[] = {
186  { "TRUNC", -1, Truncate },
187  { "ROUND", -1, Round },
188  { "FLOOR", -1, std::floor },
189  { "CEIL", -1, std::ceil },
190  { "SIGN", -1, Sign },
191  { "SQRT", -1, std::sqrt },
192  { "LOG", -1, std::log },
193  { "EXP", -1, std::exp },
194  { "SIN", -1, std::sin },
195  { "COS", -1, std::cos },
196  { "ABS", -1, std::abs },
197  { "TAN", -1, std::tan },
198  { "ASIN", -1, std::asin },
199  { "ACOS", -1, std::acos },
200  { "ATAN", -1, std::atan },
201  { "TGAUSS", -2, Tgauss },
202  { "ERF", -1, std::erf },
203  { 0, -1, 0 }
204  };
205 
206  // Real functions with two arguments.
207  // ----------------------------------------------------------------------
208 
209  double Max(double a, double b) {
210  return std::max(a, b);
211  }
212 
213  double Min(double a, double b) {
214  return std::min(a, b);
215  }
216 
217  double Mod(double a, double b) {
218  if(b <= 0.0) errno = EDOM;
219  return fmod(a, b);
220  }
221 
222  static TFunction2<double, double> power = { "^", 6, pow };
223 
224  static const TFunction2<double, double> table2[] = {
225  { "ATAN2", -1, atan2 },
226  { "MAX", -1, Max },
227  { "MIN", -1, Min },
228  { "MOD", -1, Mod },
229  { "POW", -2, pow },
230  { 0, -1, 0 }
231  };
232 
233 
234  // Function of arrays giving a real result.
235  // ----------------------------------------------------------------------
236 
237  double Mina(const std::vector<double> &array) {
238  if(array.size()) {
239  double result = array[0];
240  for(std::vector<double>::size_type i = 1; i < array.size(); ++i) {
241  result = Min(array[i], result);
242  }
243  return result;
244  } else if(Options::warn) {
245  std::cerr << "\n### Warning ### \"VMIN\" function of empty array.\n"
246  << std::endl;
247  }
248  return 0.0;
249  }
250 
251  double Maxa(const std::vector<double> &array) {
252  if(array.size()) {
253  double result = array[0];
254  for(std::vector<double>::size_type i = 1; i < array.size(); ++i) {
255  result = std::max(array[i], result);
256  }
257  return result;
258  } else if(Options::warn) {
259  std::cerr << "\n### Warning ### \"VMAX\" function of empty array.\n"
260  << std::endl;
261  }
262  return 0.0;
263  }
264 
265  double Rmsa(const std::vector<double> &array) {
266  if(array.size()) {
267  double result = 0.0;
268  for(std::vector<double>::size_type i = 0; i < array.size(); ++i) {
269  result += array[i] * array[i];
270  }
271  return sqrt(result / double(array.size()));
272  } else if(Options::warn) {
273  std::cerr << "\n### Warning ### \"VRMS\" function of empty array.\n"
274  << std::endl;
275  }
276  return 0.0;
277  }
278 
279  double AbsMax(const std::vector<double> &array) {
280  if(array.size()) {
281  double result = std::abs(array[0]);
282  for(std::vector<double>::size_type i = 1; i < array.size(); ++i) {
283  result = std::max(std::abs(array[i]), result);
284  }
285  return result;
286  } else if(Options::warn) {
287  std::cerr << "\n### Warning ### \"VABSMAX\" function of empty array.\n"
288  << std::endl;
289  }
290  return 0.0;
291  }
292 
294  static const ArrayFun tablea[] = {
295  { "VMIN", -1, Mina },
296  { "VMAX", -1, Maxa },
297  { "VRMS", -1, Rmsa },
298  { "VABSMAX", -1, AbsMax },
299  { 0, -1, 0 }
300  };
301 
302 
303  // Internal variables.
304  const Table *currentTable = 0;
306 
307 
308  // FORWARD DECLARATIONS FOR LOCAL FUNCTIONS.
309  // ------------------------------------------------------------------------
310 
311  // Parse an "&&" expression.
313 
314  // Parse an array factor.
316 
317  // Parse an array primary.
319 
320  // Parse an array term.
322 
323  // Parse a token list in brackets (for macro argument and the like).
324  // This method also checks the nesting of parentheses.
325  void parseBracketList
326  (Statement &stat, char close, std::list<Token> &result);
327 
328  // Parse a real factor.
330 
331  // Parse a real primary expression.
333 
334  // Parse a relational expression.
336 
337  // Parse a real term.
339 
340  // Parse a column generator "COLUMN(table,column,range)".
342 
343  // Parse a row generator "ROW(table,place,...)".
345 
346  // Parse a table generator "TABLE(n1:n2:n3,expr)".
348 
349 
350  // PARSE SCALAR EXPRESSIONS.
351  // ------------------------------------------------------------------------
352 
354  PtrToScalar<bool> second;
355  PtrToScalar<bool> result = parseAnd(stat);
356 
357  while(stat.delimiter("||")) {
358  second = parseAnd(stat);
359  result = SBinary<bool, bool>::make(logOr, result, second);
360  }
361 
362  return result;
363  }
364 
365 
367  PtrToScalar<double> result;
368  PtrToScalar<double> second;
369 
370  if(stat.delimiter('+')) {
371  // Unary plus.
372  result = parseTerm(stat);
373  } else if(stat.delimiter('-')) {
374  // Unary minus.
375  result = parseTerm(stat);
376  result = SUnary<double, double>::make(negate, result);
377  } else {
378  result = parseTerm(stat);
379  }
380 
381  while(true) {
382  if(stat.delimiter('+')) {
383  second = parseTerm(stat);
384  result = SBinary<double, double>::make(plus, result, second);
385  } else if(stat.delimiter('-')) {
386  second = parseTerm(stat);
387  result = SBinary<double, double>::make(minus, result, second);
388  } else {
389  break;
390  }
391  }
392 
393  return result;
394  }
395 
396 
397  double parseRealConst(Statement &stat) {
398  PtrToScalar<double> expr = parseReal(stat);
399  return expr->evaluate();
400  }
401 
402 
403  std::string parseString(Statement &stat, const char msg[]) {
404  std::string result = std::string("");
405  std::string temp;
406 
407  while(stat.word(temp) || stat.str(temp)) {
408  if(temp == "STRING") {
409  parseDelimiter(stat, '(');
410  double value = parseRealConst(stat);
411  parseDelimiter(stat, ')');
412  std::ostringstream os;
413  os << value << std::ends;
414  result += os.str();
415  } else {
416  result += temp;
417  }
418 
419  if(! stat.delimiter('&')) break;
420  }
421 
422  if(result.empty()) {
423  throw ParseError("Expressions::parseString()", msg);
424  } else {
425  return result;
426  }
427  }
428 
429 
430  // PARSE ARRAY EXPRESSIONS
431  // ------------------------------------------------------------------------
432 
434  ArrayOfPtrs<bool> array;
435 
436  if(stat.delimiter('{')) {
437  // List of boolean expressions within braces.
438  do {
439  array.push_back(parseBool(stat));
440  } while(stat.delimiter(','));
441 
442  parseDelimiter(stat, '}');
443  } else {
444  // A single boolean expression.
445  array.push_back(parseBool(stat));
446  }
447 
448  return new AList<bool>(array);
449  }
450 
451 
453  PtrToArray<double> result;
454  PtrToArray<double> second;
455 
456  if(stat.delimiter('+')) {
457  // Unary plus.
458  result = parseArrayTerm(stat);
459  } else if(stat.delimiter('-')) {
460  // Unary minus.
461  result = parseArrayTerm(stat);
462  result = new AUnary<double, double>(negate, result);
463  } else {
464  result = parseArrayTerm(stat);
465  }
466 
467  while(true) {
468  if(stat.delimiter('+')) {
469  second = parseArrayTerm(stat);
470  result = new ABinary<double, double>(plus, result, second);
471  } else if(stat.delimiter('-')) {
472  second = parseArrayTerm(stat);
473  result = new ABinary<double, double>(minus, result, second);
474  } else {
475  break;
476  }
477  }
478 
479  return result;
480  }
481 
482 
485  std::vector<double> value = arg->evaluate();
486  ArrayOfPtrs<double> array;
487 
488  for(ArrayOfPtrs<double>::size_type i = 0; i < value.size(); ++i) {
489  array.push_back(new SConstant<double>(value[i]));
490  }
491 
492  return new AList<double>(array);
493  }
494 
495 
496  std::vector<std::string> parseStringArray(Statement &stat) {
497  std::vector<std::string> array;
498 
499  if(stat.delimiter('{')) {
500  // List of string values within braces.
501  do {
502  array.push_back(parseString(stat, "String value expected."));
503  } while(stat.delimiter(','));
504 
505  parseDelimiter(stat, '}');
506  } else {
507  // A single string value.
508  array.push_back(parseString(stat, "String value expected."));
509  }
510 
511  return array;
512  }
513 
514 
515  void parseDelimiter(Statement &stat, char delim) {
516  if(! stat.delimiter(delim)) {
517  throw ParseError("Expressions::parseDelimiter()",
518  std::string("Delimiter '") + delim + "' expected.");
519  }
520  }
521 
522 
523  void parseDelimiter(Statement &stat, const char delim[2]) {
524  if(! stat.delimiter(delim)) {
525  throw ParseError("Expressions::parseDelimiter()",
526  std::string("Delimiter '") + delim + "' expected.");
527  }
528  }
529 
530 
532  if(stat.keyword("SELECTED")) {
533  return PlaceRep("SELECTED");
534  } else {
535  PlaceRep pos;
536 
537  do {
538  if(stat.delimiter('#')) {
539  static char msg[] = "Expected 'S' or 'E' after '#'.";
540  if(stat.keyword("S")) {
541  pos.append("#S", 0);
542  } else if(stat.keyword("E")) {
543  pos.append("#E", 0);
544  } else {
545  throw ParseError("Expression::parsePlace()", msg);
546  }
547  break;
548  } else {
549  std::string name = parseString(stat, "Expected <name> or '#'.");
550  int occurrence = 1;
551  if(stat.delimiter('[')) {
552  occurrence = int(Round(parseRealConst(stat)));
553  parseDelimiter(stat, ']');
554 
555  if(occurrence <= 0) {
556  throw ParseError("Expressions::parsePlace()",
557  "Occurrence counter must be positive.");
558  }
559  }
560  pos.append(name, occurrence);
561  }
562  } while(stat.delimiter("::"));
563 
564  return pos;
565  }
566  }
567 
568 
570  if(stat.keyword("FULL")) {
571  return RangeRep();
572  } else {
573  PlaceRep first = parsePlace(stat);
574  PlaceRep last = first;
575  if(stat.delimiter('/')) last = parsePlace(stat);
576  return RangeRep(first, last);
577  }
578  }
579 
580 
582  std::string objName = parseString(stat, "Object name expected.");
583 
584  // Test for attribute name.
585  std::string attrName;
586 
587  if(stat.delimiter("->")) {
588  // Reference to object attribute.
589  attrName = parseString(stat, "Attribute name expected.");
590  }
591 
592  // Parse an index, if present.
593  int index = 0;
594 
595  if(stat.delimiter('[')) {
596  index = int(Round(parseRealConst(stat)));
597  parseDelimiter(stat, ']');
598 
599  if(index <= 0) {
600  throw ParseError("Expressions::parseReference()",
601  "Index must be positive.");
602  }
603  }
604 
605  // Build reference and fill in the attribute pointer.
606  return new SRefAttr<double>(objName, attrName, index);
607  }
608 
609 
611  std::string tabName = parseString(stat, "Table name expected.");
612  parseDelimiter(stat, '@');
613  return TableRowRep(tabName, parsePlace(stat));
614  }
615 
616 
617  // ANCILLARY FUNCTIONS.
618  // ------------------------------------------------------------------------
619 
620  PtrToScalar<double>
622  currentTable = t;
623  PtrToScalar<double> result = parseReal(stat);
624  currentTable = 0;
625  return result;
626  }
627 
628 
629  std::list<Token> parseTokenList(Statement &stat) {
630  std::list<Token> result;
631 
632  while(!stat.atEnd()) {
633  stat.mark();
634  Token token = stat.getCurrent();
635 
636  // End of list if one of the following tokens occurs outside
637  // of brackets.
638  if(token.isDel(',') || token.isDel(';') || token.isDel(')') ||
639  token.isDel(']') || token.isDel('}')) {
640  // Must reread the terminating token.
641  stat.restore();
642  break;
643  }
644 
645  result.push_back(token);
646 
647  if(token.isDel('(')) {
648  parseBracketList(stat, ')', result);
649  } else if(token.isDel('[')) {
650  parseBracketList(stat, ']', result);
651  } else if(token.isDel('{')) {
652  parseBracketList(stat, '}', result);
653  }
654  }
655 
656  return result;
657  }
658 
659 
660  std::vector<std::list<Token> > parseTokenListArray(Statement &stat) {
661  std::vector<std::list<Token> > array;
662 
663  if(stat.delimiter('{')) {
664  // List of token lists within braces.
665  do {
666  array.push_back(parseTokenList(stat));
667  } while(stat.delimiter(','));
668 
669  parseDelimiter(stat, '}');
670  } else {
671  // A single token list.
672  array.push_back(parseTokenList(stat));
673  }
674 
675  return array;
676  }
677 
678 
679  // LOCAL FUNCTIONS.
681  PtrToScalar<bool> result = parseRelation(stat);
682  PtrToScalar<bool> second;
683 
684  while(stat.delimiter("&&")) {
685  second = parseRelation(stat);
686  result = SBinary<bool, bool>::make(logAnd, result, second);
687  }
688 
689  return result;
690  }
691 
692 
694  PtrToArray<double> result = parseArrayPrimary(stat);
695  PtrToArray<double> second;
696 
697  if(stat.delimiter('^')) {
698  second = parseArrayPrimary(stat);
699  result = new ABinary<double, double>(power, result, second);
700  }
701 
702  return result;
703  }
704 
705 
707  PtrToArray<double> result;
708  double value;
709 
710  if(stat.delimiter('(')) {
711  result = parseRealArray(stat);
712  parseDelimiter(stat, ')');
713  } else if(stat.delimiter('{')) {
714  ArrayOfPtrs<double> array;
715  do {
716  array.push_back(parseReal(stat));
717  } while(stat.delimiter(','));
718  parseDelimiter(stat, '}');
719  result = new AList<double>(array);
720  } else if(stat.keyword("COLUMN")) {
721  result = parseColumnGenerator(stat);
722  } else if(stat.keyword("ROW")) {
723  result = parseRowGenerator(stat);
724  } else if(stat.keyword("TABLE")) {
725  result = parseTableGenerator(stat);
726  } else if(stat.real(value)) {
727  ArrayOfPtrs<double> array;
728  array.push_back(new SConstant<double>(value));
729  result = new AList<double>(array);
730  } else {
731  std::string frstName = parseString(stat, "Object name expected.");
732  if(stat.delimiter('(')) {
733  // Possible function call.
734  PtrToArray<double> arg1;
735  PtrToArray<double> arg2;
736  if(const TFunction2<double, double> *fun = find(table2, frstName)) {
737  arg1 = parseRealArray(stat);
738  parseDelimiter(stat, ',');
739  arg2 = parseRealArray(stat);
740  result = new ABinary<double, double>(*fun, arg1, arg2);
741  } else if(const TFunction1<double, double> *fun =
742  find(table1, frstName)) {
743  arg1 = parseRealArray(stat);
744  result = new AUnary<double, double>(*fun, arg1);
745  } else if(frstName == "EVAL") {
746  result = parseRealConstArray(stat);
747  } else if(const TFunction0<double> *fun = find(table0, frstName)) {
748  ArrayOfPtrs<double> array;
749  array.push_back(SNull<double>::make(*fun));
750  result = new AList<double>(array);
751  } else if(const ArrayFun *fun = find(tablea, frstName)) {
752  PtrToArray<double> arg1 = parseRealArray(stat);
753  ArrayOfPtrs<double> array;
754  array.push_back(new ASUnary<double>(*fun, arg1));
755  result = new AList<double>(array);
756  } else {
757  throw ParseError("parseArrayPrimary()",
758  "Invalid array function name \"" + frstName +
759  "\".");
760  }
761  parseDelimiter(stat, ')');
762  } else if(stat.delimiter("->")) {
763  std::string scndName = parseString(stat, "Attribute name expected.");
764  result = new ARefExpr<double>(frstName, scndName);
765  } else if(stat.delimiter('@')) {
766  PlaceRep row = parsePlace(stat);
767  // Possible column names.
768  if(stat.delimiter("->")) {
769  std::vector<std::string> cols = parseStringArray(stat);
770  result = new ARow(frstName, row, cols);
771  } else {
772  throw ParseError("Expressions::parseReal()",
773  "Expected a column name.");
774  }
775  } else {
776  result = new ARefExpr<double>(frstName, "");
777  }
778  }
779 
780  return result;
781  }
782 
783 
785  PtrToArray<double> result = parseArrayFactor(stat);
786  PtrToArray<double> second;
787 
788  while(true) {
789  if(stat.delimiter('*')) {
790  second = parseArrayFactor(stat);
791  result = new ABinary<double, double>(times, result, second);
792  } else if(stat.delimiter('/')) {
793  second = parseArrayFactor(stat);
794  result = new ABinary<double, double>(divide, result, second);
795  } else {
796  break;
797  }
798  }
799 
800  return result;
801  }
802 
803 
804  void parseBracketList(Statement &stat, char close, std::list<Token> &result) {
805  while(true) {
806  if(stat.atEnd() || stat.delimiter(';')) {
807  throw ParseError("Expressions::parseBracketList()",
808  "Parentheses, brackets or braces do not nest.");
809  }
810 
811  Token token = stat.getCurrent();
812  result.push_back(token);
813 
814  if(token.isDel('(')) {
815  parseBracketList(stat, ')', result);
816  } else if(token.isDel('[')) {
817  parseBracketList(stat, ']', result);
818  } else if(token.isDel('{')) {
819  parseBracketList(stat, '}', result);
820  } else if(token.isDel(close)) {
821  return;
822  }
823  }
824  }
825 
826 
828  PtrToScalar<double> result = parsePrimary(stat);
829  PtrToScalar<double> second;
830 
831  if(stat.delimiter('^')) {
832  second = parsePrimary(stat);
833  result = SBinary<double, double>::make(power, result, second);
834  }
835 
836  return result;
837  }
838 
839 
841  PtrToScalar<double> arg1;
842  PtrToScalar<double> arg2;
843  PtrToScalar<double> result;
844  double value;
845 
846  if(stat.delimiter('(')) {
847  // Expression in "(...)".
848  result = parseReal(stat);
849  parseDelimiter(stat, ')');
850  } else if(stat.real(value)) {
851  // Litteral constant.
852  result = new SConstant<double>(value);
853  } else if(currentArray.isValid() && stat.delimiter('#')) {
854  // "#" hash expression
855  result = new SHash(*currentArray);
856  } else {
857  // Primary beginning with a name.
858  std::string frstName = parseString(stat, "Real primary expected.");
859 
860  if(stat.delimiter('(')) {
861  // Possible function call.
862  if(const TFunction2<double, double> *fun = find(table2, frstName)) {
863  arg1 = parseReal(stat);
864  parseDelimiter(stat, ',');
865  arg2 = parseReal(stat);
866  result = SBinary<double, double>::make(*fun, arg1, arg2);
867  } else if(const TFunction1<double, double> *fun =
868  find(table1, frstName)) {
869  arg1 = parseReal(stat);
870  result = SUnary<double, double>::make(*fun, arg1);
871  } else if(frstName == "EVAL") {
872  result = new SConstant<double>(parseRealConst(stat));
873  } else if(const TFunction0<double> *fun = find(table0, frstName)) {
874  result = SNull<double>::make(*fun);
875  } else if(const ArrayFun *fun = find(tablea, frstName)) {
876  PtrToArray<double> arg1 = parseRealArray(stat);
877  result = new ASUnary<double>(*fun, arg1);
878  } else {
879  throw ParseError("parsePrimary()",
880  "Unknown function name \"" + frstName + "\".");
881  }
882  parseDelimiter(stat, ')');
883  } else if(stat.delimiter("->")) {
884  // Possible parameter or object->attribute clause.
885  std::string scndName =
886  parseString(stat, "Attribute or element name expected.");
887 
888  // Possible index.
889  if(stat.delimiter('[')) {
890  arg2 = parseReal(stat);
891  parseDelimiter(stat, ']');
892  PtrToArray<double> arg1 =
893  new ARefExpr<double>(frstName, scndName);
894  result = new Indexer<double>(arg1, arg2);
895  } else {
896  result = new SRefExpr<double>(frstName, scndName);
897  }
898  } else if(stat.delimiter('@')) {
899  PlaceRep row = parsePlace(stat);
900  // Possible column name.
901  if(stat.delimiter("->")) {
902  std::string col = parseString(stat, "Column name expected.");
903  result = new SCell(frstName, row, col);
904  } else {
905  throw ParseError("Expressions::parseReal()",
906  "Expected a column name.");
907  }
908  } else {
909  // If the name is indexed, the name must be a global vector.
910  if(stat.delimiter('[')) {
911  arg2 = parseReal(stat);
912  parseDelimiter(stat, ']');
913  PtrToArray<double> arg1 = new ARefExpr<double>(frstName, "");
914  result = new Indexer<double>(arg1, arg2);
915  } else if(currentTable) {
916  // Try making a column expression.
917  result = currentTable->makeColumnExpression(frstName);
918  if(! result.isValid()) {
919  // Could not make a column expression from this name.
920  result = new SRefExpr<double>(frstName, "");
921  }
922  } else {
923  // Simple name must be a global variable.
924  result = new SRefExpr<double>(frstName, "");
925  }
926  }
927  }
928 
929  return result;
930  }
931 
932 
934  PtrToScalar<double> first;
935  PtrToScalar<double> second;
936  PtrToScalar<bool> result;
937  bool value;
938  std::string name;
939 
940  if(stat.delimiter('(')) {
941  result = parseBool(stat);
942  parseDelimiter(stat, ')');
943  } else if(stat.boolean(value)) {
944  result = new SConstant<bool>(value);
945  } else {
946  stat.mark();
947  BoolConstant *bc = 0;
948  if(stat.word(name) &&
949  (bc = dynamic_cast<BoolConstant *>(OpalData::getInstance()->find(name)))) {
950  return new SConstant<bool>(bc->getBool());
951  }
952 
953  stat.restore();
954  first = parseReal(stat);
955  const TFunction2<bool, double> *code = 0;
956  if(stat.delimiter('<')) {
957  code = &less;
958  } else if(stat.delimiter('>')) {
959  code = &greater;
960  } else if(stat.delimiter(">=")) {
961  code = &greaterEqual;
962  } else if(stat.delimiter("<=")) {
963  code = &lessEqual;
964  } else if(stat.delimiter("==")) {
965  code = &equal;
966  } else if(stat.delimiter("!=")) {
967  code = &notEqual;
968  } else {
969  throw ParseError("parseRelation()",
970  "Invalid boolean expression.");
971  }
972  second = parseReal(stat);
973  result = SBinary<bool, double>::make(*code, first, second);
974  }
975 
976  return result;
977  }
978 
979 
981  PtrToScalar<double> result = parseFactor(stat);
982  PtrToScalar<double> second;
983 
984  while(true) {
985  if(stat.delimiter('*')) {
986  second = parseFactor(stat);
987  result = SBinary<double, double>::make(times, result, second);
988  } else if(stat.delimiter('/')) {
989  second = parseFactor(stat);
990  result = SBinary<double, double>::make(divide, result, second);
991  } else {
992  break;
993  }
994  }
995 
996  return result;
997  }
998 
999 
1001  // COLUMN function builds an array from a table column.
1002  // format: COLUMN(<table>, <column>) or
1003  // COLUMN(<table>, <column>, <range>).
1004  // The word "COLUMN" has already been seen by the caller.
1005  parseDelimiter(stat, '(');
1006  std::string tabName = parseString(stat, "Table name expected.");
1007 
1008  // Column name.
1009  parseDelimiter(stat, ',');
1010  std::string colName = parseString(stat, "Column name expected.");
1011 
1012  // Optional range specification.
1013  RangeRep range;
1014  if(stat.delimiter(',')) {
1015  range = parseRange(stat);
1016  }
1017 
1018  parseDelimiter(stat, ')');
1019  return new AColumn(tabName, colName, range);
1020  }
1021 
1022 
1024  // ROW function builds an array from a table row.
1025  // format: ROW(<table>, <place>) or
1026  // ROW(<table>, <place>, <columns>).
1027  // The word "ROW" has already been seen by the caller.
1028  parseDelimiter(stat, '(');
1029  std::string tabName = parseString(stat, "Table name expected.");
1030 
1031  // Row position.
1032  parseDelimiter(stat, ',');
1033  PlaceRep row = parsePlace(stat);
1034 
1035  // Optional column specifications.
1036  std::vector<std::string> columns;
1037  if(stat.delimiter(',')) {
1038  columns = parseStringArray(stat);
1039  parseDelimiter(stat, ')');
1040  }
1041 
1042  return new ARow(tabName, row, columns);
1043  }
1044 
1046  // TABLE function generates an array from expressions.
1047  // format: "TABLE(<n>, <real>)" or
1048  // "TABLE(<n1>:<n2>, <real>)" or
1049  // "TABLE(<n1>:<n2>:<dn>, <real>)".
1050  // The word "TABLE" has already been read by the caller.
1051  parseDelimiter(stat, '(');
1052 
1053  // Read the array index set.
1054  int frst = int(Round(parseRealConst(stat)));
1055  int last = 1;
1056  int step = 1;
1057 
1058  if(stat.delimiter(',')) {
1059  last = frst;
1060  frst = 1;
1061  } else if(stat.delimiter(':')) {
1062  last = int(Round(parseRealConst(stat)));
1063  if(stat.delimiter(':')) {
1064  step = int(Round(parseRealConst(stat)));
1065  }
1066  parseDelimiter(stat, ',');
1067  } else {
1068  throw ParseError("Expressions::parseTableGenerator()",
1069  "Index set incorrect or missing.");
1070  }
1071 
1072  // Check the array index set.
1073  if(frst <= 0 || last <= 0 || step <= 0) {
1074  throw ParseError("Expressions::parseTableGenerator()",
1075  "Invalid array index set.");
1076  }
1077 
1078  // Construct the expression generator.
1079  currentArray = new ATable(frst, last, step);
1080  currentArray->defineExpression(parseReal(stat));
1081  parseDelimiter(stat, ')');
1082 
1083  // The call to release() is required because of type constraints.
1084  return currentArray.release();
1085  }
1086 
1087 }
double AbsMax(const std::vector< double > &array)
An expression defined as a reference to a scalar.
Definition: SRefExpr.h:41
double Round(double value)
Round the double argument.
Definition: Round.cpp:23
PtrToScalar< bool > parseRelation(Statement &stat)
void parseBracketList(Statement &stat, char close, std::list< Token > &result)
An array expression generated from a TABLE() function.
Definition: ATable.h:38
PartBunchBase< double, 3 > * getPartBunch()
Definition: OpalData.cpp:421
A scalar expression without operands.
Definition: SNull.h:38
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
PETE_TUTree< FnArcCos, typename T::PETE_Expr_t > acos(const PETE_Expr< T > &l)
Definition: PETE.h:808
double parseRealConst(Statement &)
Parse real constant.
PtrToArray< double > parseArrayTerm(Statement &stat)
bool keyword(const char *s)
Test for keyword.
Definition: Statement.cpp:123
bool Ge(double a, double b)
Definition: Expressions.cpp:88
PlaceRep parsePlace(Statement &)
Parse place specification.
Parse exception.
Definition: ParseError.h:32
A scalar constant expression.
Definition: SConstant.h:35
A scalar expression to retrieve an indexed component from an array.
Definition: Indexer.h:40
static Scalar< T > * make(const TFunction0< T > &function)
Make expression.
Definition: SNull.h:124
void mark()
Mark position in command.
Definition: Statement.cpp:172
PtrToScalar< double > parseReal(Statement &)
Parse real expression.
FTps< T, N > erf(const FTps< T, N > &x, int trunc=(FTps< T, N >::EXACT))
Error function.
Definition: FTpsMath.h:385
double gauss()
A pointer to a scalar expression.
Definition: Expressions.h:116
virtual Expressions::PtrToScalar< double > makeColumnExpression(const std::string &) const =0
static double arcIn()
Return arc length at entrance SI().
Definition: SFunction.cpp:43
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:123
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
RangeRep parseRange(Statement &)
Parse range specification.
bool Gt(double a, double b)
Definition: Expressions.cpp:91
PETE_TUTree< FnCeil, typename T::PETE_Expr_t > ceil(const PETE_Expr< T > &l)
Definition: PETE.h:811
static double arcOut()
Return arc length at exit SO().
Definition: SFunction.cpp:65
Tps< T > exp(const Tps< T > &x)
Exponential.
Definition: TpsMath.h:165
bool atEnd() const
Test for end of command.
Definition: Statement.cpp:52
double get_meanKineticEnergy() const
TFunction1< double, const std::vector< double > & > ArrayFun
double Add(double a, double b)
double Rmsa(const std::vector< double > &array)
A function of two U&#39;s returning a T.
Definition: TFunction2.h:31
Tps< T > tan(const Tps< T > &x)
Tangent.
Definition: TpsMath.h:147
PtrToArray< double > parseRowGenerator(Statement &stat)
A pointer which owns the object pointed at.
Definition: OwnPtr.h:31
void gauss(double &gr1, double &gr2)
Gaussian distribution.
void restore()
Return to marked position.
Definition: Statement.cpp:177
bool warn
Warn flag.
Definition: Options.cpp:10
Representation of a table row reference.
Definition: TableRowRep.h:36
Tps< T > log(const Tps< T > &x)
Natural logarithm.
Definition: TpsMath.h:182
bool real(double &value)
Return real value.
Definition: Statement.cpp:133
double Sub(double a, double b)
SRefAttr< double > * parseReference(Statement &)
Parse variable reference.
bool Eq(double a, double b)
Definition: Expressions.cpp:94
bool And(bool a, bool b)
Definition: Expressions.cpp:79
double Truncate(double value)
Truncate.
Definition: Truncate.cpp:23
An attribute defined as a reference to a scalar.
Definition: Expressions.h:248
void parseDelimiter(Statement &stat, char delim)
Test for one-character delimiter.
static double arcCtr()
Return arc length at center SC().
Definition: SFunction.cpp:54
bool word(std::string &value)
Return word value.
Definition: Statement.cpp:161
Representation of a place within a beam line or sequence.
Definition: PlaceRep.h:41
double Tgauss(double a)
static Scalar< T > * make(const TFunction1< T, U > &function, PtrToScalar< U > operand)
Make a new expression.
Definition: SUnary.h:135
static OpalData * getInstance()
Definition: OpalData.cpp:209
PtrToScalar< bool > parseBool(Statement &)
Parse boolean expression.
double Mina(const std::vector< double > &array)
bool boolean(bool &value)
Return boolean value.
Definition: Statement.cpp:57
A scalar expression referring to a table cell.
Definition: SCell.h:36
PtrToScalar< double > parseTerm(Statement &stat)
PtrToScalar< double > parseFactor(Statement &stat)
virtual bool getBool() const
Return value.
Random rangen
Random generator.
Definition: Options.cpp:38
double Max(double a, double b)
A function of one U, returning a T.
Definition: TFunction1.h:31
Interface for statements.
Definition: Statement.h:38
void append(const std::string &, int occur)
Add a name/occurrence pair.
Definition: PlaceRep.cpp:59
PtrToArray< double > parseColumnGenerator(Statement &stat)
PETE_TUTree< FnArcTan, typename T::PETE_Expr_t > atan(const PETE_Expr< T > &l)
Definition: PETE.h:810
An array expression defined as a table column.
Definition: AColumn.h:36
Representation of a single input token.
Definition: Token.h:33
double Mod(double a, double b)
double uniform()
Uniform distribution.
TableRowRep parseTableRow(Statement &)
Parse a token list (for macro argument and the like).
PETE_TBTree< FnArcTan2, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > atan2(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
An array expression with two array operands.
Definition: ABinary.h:41
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
bool isValid() const
Test for validity.
Definition: OwnPtr.h:144
Representation of a range within a beam line or sequence.
Definition: RangeRep.h:34
PETE_TBTree< FnFmod, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > fmod(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
bool Lt(double a, double b)
Definition: Expressions.cpp:85
arg(a))
std::vector< std::string > parseStringArray(Statement &)
Parse string array.
const T * find(const T table[], const std::string &name)
Look up name.
Definition: TFind.h:34
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
double Neg(double a)
double ranf()
double Maxa(const std::vector< double > &array)
bool Or(bool a, bool b)
Definition: Expressions.cpp:76
double Min(double a, double b)
PtrToArray< double > parseRealArray(Statement &)
Parse real array expression.
PtrToScalar< double > parseTableExpression(Statement &, const Table *)
Parse table expression (depends on a table&#39;s rows).
An array of pointers to scalar expressions.
Definition: Expressions.h:134
bool Ne(double a, double b)
Definition: Expressions.cpp:97
double getEkin()
Object * find(const std::string &name)
Find entry.
Definition: OpalData.cpp:618
A scalar expression.
Definition: SHash.h:37
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
const Table * currentTable
The BOOL CONSTANT definition.
Definition: BoolConstant.h:27
const std::string name
An array expression with one array operand.
Definition: AUnary.h:40
std::list< Token > parseTokenList(Statement &)
Parse a token list (for macro argument and the like).
double Sign(double a)
bool str(std::string &value)
Return string value.
Definition: Statement.cpp:150
virtual std::vector< T > evaluate() const =0
Evaluate.
An expression defined as a reference to an array.
Definition: ARefExpr.h:42
PtrToArray< double > parseTableGenerator(Statement &stat)
double Mpy(double a, double b)
Token & getCurrent()
Return current token and skip it.
Definition: Statement.cpp:76
PtrToArray< double > parseArrayPrimary(Statement &stat)
PETE_TUTree< FnArcSin, typename T::PETE_Expr_t > asin(const PETE_Expr< T > &l)
Definition: PETE.h:809
An operand-less function returning a T.
Definition: TFunction0.h:31
An array expression defined as a table row.
Definition: ARow.h:35
bool isDel(char del) const
Test for delimiter.
Definition: Token.cpp:92
bool Le(double a, double b)
Definition: Expressions.cpp:82
OwnPtr< ATable > currentArray
std::string parseString(Statement &, const char msg[])
Parse string value.
PtrToArray< double > parseRealConstArray(Statement &)
Parse real array constant.
The base class for all OPAL tables.
Definition: Table.h:42
bool delimiter(char c)
Test for delimiter.
Definition: Statement.cpp:103
PtrToArray< bool > parseBoolArray(Statement &)
Parse boolean array expression.
static Scalar< T > * make(const TFunction2< T, U > &, PtrToScalar< U > left, PtrToScalar< U > right)
Make a new expression.
Definition: SBinary.h:136
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:95
PtrToScalar< double > parsePrimary(Statement &stat)
A pointer to an array expression.
Definition: Expressions.h:186
std::vector< std::list< Token > > parseTokenListArray(Statement &)
Parse a token list array (for LIST commands).
PtrToArray< double > parseArrayFactor(Statement &stat)
double Div(double a, double b)
PETE_TUTree< FnFloor, typename T::PETE_Expr_t > floor(const PETE_Expr< T > &l)
Definition: PETE.h:816
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
A scalar expression with one array operand.
Definition: ASUnary.h:41
PtrToScalar< bool > parseAnd(Statement &stat)
An array expression defined by a list of scalar expressions.
Definition: AList.h:36