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