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