OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
OpalParser.cpp
Go to the documentation of this file.
1 
2 // ------------------------------------------------------------------------
3 // $RCSfile: OpalParser.cpp,v $
4 // ------------------------------------------------------------------------
5 // $Revision: 1.3 $
6 // ------------------------------------------------------------------------
7 // Copyright: see Copyright.readme
8 // ------------------------------------------------------------------------
9 //
10 // Class OpalParser:
11 // This is the default parser for OPAL statements.
12 //
13 // ------------------------------------------------------------------------
14 //
15 // $Date: 2001/08/13 15:17:27 $
16 // $Author: jowett $
17 //
18 // ------------------------------------------------------------------------
19 
20 #include "OpalParser/OpalParser.h"
21 #include "AbstractObjects/Action.h"
25 #include "AbstractObjects/Object.h"
27 #include "Attributes/Attributes.h"
29 #include "OpalParser/IfStatement.h"
32 #include "Parser/SimpleStatement.h"
33 #include "Parser/Token.h"
35 #include "Utilities/ParseError.h"
36 #include "Utilities/Options.h"
37 #include "Utilities/Round.h"
38 #include <cassert>
39 #include <ctime>
40 #include <exception>
41 #include <iostream>
42 #include <new>
43 #include <boost/algorithm/string.hpp>
44 
45 #include <Ippl.h>
46 
47 using namespace Expressions;
48 
49 extern Inform *gmsg;
50 
51 // Class OpalParser
52 // ------------------------------------------------------------------------
53 
54 std::vector<Pointer<TokenStream> > OpalParser::inputStack;
55 
56 
57 OpalParser::OpalParser(): stopFlag(false)
58 {}
59 
60 
62 {}
63 
64 
65 void OpalParser::parse(Statement &stat) const {
66  if(stat.keyword("SHARED")) {
67  // "SHARED ...": Shared object definition.
68  parseDefine(stat);
69  } else if(stat.keyword("CONSTANT") || stat.keyword("CONST") ||
70  stat.keyword("BOOL") || stat.keyword("REAL") ||
71  stat.keyword("STRING") || stat.keyword("VECTOR")) {
72  // Keywords introducing variable definitions.
73  parseAssign(stat);
74  } else {
75  std::string name = parseString(stat, "Identifier or keyword expected.");
76 
77  if(stat.delimiter('?')) {
78  // "<class>?": give help for class.
79  printHelp(name);
80  } else if(stat.delimiter(':')) {
81  // "<object>:<class>...": labeled command.
82  parseDefine(stat);
83  } else if(stat.delimiter('(')) {
84  // "<macro>(...)...": macro definition or call.
85  // We are positioned just after the '(' of the argument list.
86  parseMacro(name, stat);
87  } else if(stat.delimiter(',') || stat.delimiter(';') ||
88  stat.atEnd()) {
89  // "<class>" or "<class>,<attributes>": Executable command.
90  parseAction(stat);
91  } else {
92  // Assignment beginning with a name.
93  stat.mark();
94  stat.start();
95  std::string objName = parseString(stat, "Object name expected.");
96  if (OpalData::getInstance()->find(objName) == 0) {
97  Token tok = stat.getCurrent();
98  stat.restore();
99 
100  std::string name = tok.getLex();
101  std::string hint = getHint(name);
102  unsigned int position = stat.position();
103  std::string positionIndicator = std::string(position, ' ') + "^\n";
104  std::ostringstream statStr;
105  stat.print(statStr);
106  if (hint != "") {
107  throw ParseError("OpalParser::parse()",
108  statStr.str() +
109  positionIndicator +
110  "Syntax error, either the keyword REAL is missing or\n" +
111  hint);
112  } else {
113  throw ParseError("OpalParser::parse()",
114  statStr.str() +
115  positionIndicator +
116  "Syntax error, the keyword REAL is missing\n");
117  }
118  }
119  parseAssign(stat);
120  }
121  }
122 }
123 
124 
125 void OpalParser::execute(Object *object, const std::string &name) const {
126  // Trace execution.
127  if(Options::mtrace && object->shouldTrace()) {
128  double time = double(clock()) / double(CLOCKS_PER_SEC);
129  *gmsg << "\nBegin execution: \"" << name
130  << "\", CPU time = " << time << " seconds.\n" << endl;
131  }
132 
133  // Force updating of all attributes which might have been changed.
134  if(object->shouldUpdate()) {
136  }
137 
138  // Execute or check the command.
139  object->execute();
140 
141  // Trace execution.
142  if(Options::mtrace && object->shouldTrace()) {
143  double time = double(clock()) / double(CLOCKS_PER_SEC);
144  *gmsg << "\nEnd execution: \"" << name
145  << "\", CPU time = " << time << " seconds.\n" << endl;
146  }
147 }
148 
149 
150 Object *OpalParser::find(const std::string &name) const {
151  return OpalData::getInstance()->find(name);
152 }
153 
154 
156  stat.start();
157  std::string cmdName = parseString(stat, "Command name expected");
158 
159  if(cmdName == "STOP") {
160  stopFlag = true;
161  } else if(cmdName == "QUIT") {
162  stopFlag = true;
163  } else if(cmdName == "HELP" && stat.delimiter(',')) {
164  cmdName = parseString(stat, "Object name expected");
165  printHelp(cmdName);
166  } else if(Object *object = find(cmdName)) {
167  Object *copy = 0;
168  try {
169  copy = object->clone("");
170  copy->parse(stat);
171  parseEnd(stat);
172  execute(copy, cmdName);
173  delete copy;
174  } catch (...) {
175  delete copy;
176  throw;
177  }
178  } else {
179  std::string hint = getHint(cmdName, "command");
180  if (hint != "") {
181  throw ParseError("OpalParser::parse()",
182  "Syntax error, " + hint);
183  }
184 
185  throw ParseError("OpalParser::parseAction()",
186  "Command \"" + cmdName + "\" is unknown.");
187  }
188 }
189 
190 
192  stat.start();
193 
194  // Find various model objects.
195  /*static*/
196  Object *boolConstant = OpalData::getInstance()->find("BOOL_CONSTANT");
197  /*static*/
198  Object *realConstant = OpalData::getInstance()->find("REAL_CONSTANT");
199  /*static*/
200  Object *realVariable = OpalData::getInstance()->find("REAL_VARIABLE");
201  /*static*/
202  Object *realVector = OpalData::getInstance()->find("REAL_VECTOR");
203  /*static*/
204  Object *stringConstant = OpalData::getInstance()->find("STRING_CONSTANT");
205 
206  // Gobble up any prefix.
207  int code = 0x00;
208  while(true) {
209  if(stat.keyword("CONSTANT") || stat.keyword("CONST")) {
210  code |= 0x01;
211  } else if(stat.keyword("BOOL")) {
212  code |= 0x02;
213  } else if(stat.keyword("REAL")) {
214  code |= 0x04;
215  } else if(stat.keyword("STRING")) {
216  code |= 0x08;
217  } else if(stat.keyword("VECTOR")) {
218  code |= 0x10;
219  } else {
220  break;
221  }
222  }
223 
224  std::string objName = parseString(stat, "Object name expected.");
225  // Test for attribute name.
226  Object *object = 0;
227  std::string attrName;
228 
229  if(stat.delimiter("->")) {
230  // Assignment to object attribute.
231  attrName = parseString(stat, "Attribute name expected.");
232 
233  if(code != 0) {
234  throw ParseError("OpalParser::parseAssign()",
235  "Invalid type specification for this value.");
236  } else if((object = OpalData::getInstance()->find(objName)) == 0) {
237  throw ParseError("OpalParser::parseAssign()",
238  "The object \"" + objName + "\" is unknown.");
239  }
240  } else {
241  // Assignment to variable-like object.
242  if((object = OpalData::getInstance()->find(objName)) == 0) {
243  Object *model = 0;
244  switch(code) {
245  case 0x01: // CONSTANT
246  case 0x05: // CONSTANT REAL
247  model = realConstant;
248  break;
249  case 0x02: // BOOL
250  case 0x03: // BOOL CONSTANT
251  model = boolConstant;
252  break;
253  case 0x00: // empty <type>.
254  case 0x04: // REAL
255  model = realVariable;
256  break;
257  case 0x10: // VECTOR
258  case 0x11: // CONSTANT VECTOR
259  case 0x14: // REAL VECTOR
260  case 0x15: // CONSTANT REAL VECTOR
261  model = realVector;
262  break;
263  case 0x08: // STRING
264  case 0x09: // STRING CONSTANT
265  model = stringConstant;
266  break;
267  default:
268  break;
269  }
270 
271  if(model != 0) {
272  object = model->clone(objName);
273  OpalData::getInstance()->define(object);
274  } else {
275  throw ParseError("OpalParser::parseAssign()", "Invalid <type> field.");
276  }
277  } else if(object->isTreeMember(realConstant)) {
278  throw ParseError("OpalParser::parseAssign()",
279  "You cannot redefine the constant \"" + objName + "\".");
280  }
281 
282  attrName = "VALUE";
283  }
284 
285  // Test for index; it is evaluated immediately.
286  int index = 0;
287 
288  if(stat.delimiter('[')) {
289  index = int(Round(parseRealConst(stat)));
290  parseDelimiter(stat, ']');
291 
292  if(index <= 0) {
293  throw ParseError("Expressions::parseReference()",
294  "Index must be positive.");
295  }
296  }
297 
298  if(object != 0) {
299  if(Attribute *attr = object->findAttribute(attrName)) {
300  if(stat.delimiter('=') || object->isTreeMember(realConstant)) {
301  if(index > 0) {
302  attr->parseComponent(stat, true, index);
303  } else {
304  attr->parse(stat, true);
305  }
306  } else if(stat.delimiter(":=")) {
307  if(index > 0) {
308  attr->parseComponent(stat, false, index);
309  } else {
310  attr->parse(stat, false);
311  }
312  }
313  } else {
314  throw ParseError("OpalParser::parseAssign()",
315  "Object \"" + objName + "\" has no attribute \"" +
316  attrName + "\".");
317  }
318 
319  parseEnd(stat);
320  OpalData::getInstance()->makeDirty(object);
321  }
322 }
323 
324 
326  stat.start();
327  bool isShared = stat.keyword("SHARED");
328  std::string objName = parseString(stat, "Object name expected.");
329 
330  if(stat.delimiter(':')) {
331  std::string clsName = parseString(stat, "Class name expected.");
332  Object *classObject = find(clsName);
333 
334  if(classObject == 0) {
335  if (clsName == "SURFACEPHYSICS")
336  throw ParseError("OpalParser::parseDefine()",
337  "The object \"" + clsName + "\" is changed to \"PARTICLEMATTERINTERACTION\".");
338  else
339  throw ParseError("OpalParser::parseDefine()",
340  "The object \"" + clsName + "\" is unknown.");
341  }
342 
343  Object *copy = 0;
344  try {
345  if(stat.delimiter('(')) {
346  // Macro-like objects are always classes, instances never.
347  // There is no further check required.
348  copy = classObject->makeInstance(objName, stat, this);
349  } else {
350  copy = classObject->clone(objName);
351  copy->parse(stat);
352  copy->setShared(isShared);
353  }
354 
355  parseEnd(stat);
356  execute(copy, clsName);
357  OpalData::getInstance()->define(copy);
358  } catch(...) {
359  delete copy;
360  throw;
361  }
362  } else {
363  // Redefine an object to be a class.
364  Object *classObject = find(objName);
365  Object *copy = classObject->clone(objName);
366  copy->parse(stat);
367  copy->setShared(isShared);
368  }
369 }
370 
371 
372 void OpalParser::parseEnd(Statement &stat) const {
373  if(! stat.atEnd() && ! stat.delimiter(';')) {
374 
375  unsigned int position = stat.position();
376  std::string positionIndicator = std::string(position + 1, ' ') + "^\n";
377  std::ostringstream statStr;
378  stat.print(statStr);
379 
380  throw ParseError("OpalParser::parseEnd()",
381  statStr.str() +
382  positionIndicator +
383  "Syntax error (maybe missing comma or semicolon ? )");
384  }
385 }
386 
387 
388 void OpalParser::parseMacro(const std::string &macName, Statement &stat) const {
389  // Record the position just after the '(' of the argument list.
390  stat.mark();
391 
392  // Skip argument list.
393  int par_level = 1;
394  while(true) {
395  if(stat.delimiter('(')) {
396  ++par_level;
397  } else if(stat.delimiter(')')) {
398  if(--par_level == 0) break;
399  } else {
400  stat.getCurrent();
401  }
402  }
403 
404  if(stat.delimiter(':')) {
405  // Macro definition.
406  std::string className = parseString(stat, "Class name expected.");
407 
408  if(Object *macro = OpalData::getInstance()->find(className)) {
409  // Backtrack to first argument.
410  stat.restore();
411 
412  if(Object *copy =
413  macro->makeTemplate(macName, *inputStack.back(), stat)) {
414  OpalData::getInstance()->define(copy);
415  } else {
416  throw ParseError("OpalParser::parseMacro()", "Command \"" +
417  macName + "\" cannot be defined with arguments.");
418  }
419  } else {
420  throw ParseError("OpalParser::parseMacro()",
421  "Object \"" + className + "\" is unknown.");
422  }
423  } else {
424  // Macro call.
425  if(Object *macro = OpalData::getInstance()->find(macName)) {
426  // Backtrack to first argument.
427  stat.restore();
428  Object *instance = 0;
429  try {
430  instance = macro->makeInstance(macName, stat, this);
431  execute(instance, macName);
432  } catch(...) {
433  delete instance;
434  throw;
435  }
436  } else {
437  throw ParseError("OpalParser::parseMacro()",
438  "Macro \"" + macName + "\" is unknown.");
439  }
440  }
441 }
442 
443 
444 void OpalParser::printHelp(const std::string &cmdName) const {
445  Object *object = find(cmdName);
446 
447  if(object == 0) {
448  *gmsg << "\nOpalParser::printHelp(): Unknown object \""
449  << cmdName << "\".\n" << endl;
450  } else {
451  object->printHelp(std::cerr);
452  }
453 }
454 
455 
456 void OpalParser::parseBracketList(char close, Statement &stat) {
457  Token token = readToken();
458 
459  while(! token.isEOF()) {
460  stat.append(token);
461 
462  if(token.isDel('(')) {
463  parseBracketList(')', stat);
464  } else if(token.isDel('[')) {
465  parseBracketList(']', stat);
466  } else if(token.isDel('{')) {
467  parseBracketList('}', stat);
468  } else if(token.isDel(close)) {
469  return;
470  }
471 
472  token = readToken();
473  }
474 }
475 
476 
478  Token token = readToken();
479 
480  while(! token.isEOF()) {
481  // End of list if semicolon occurs outside of brackets.
482  if(token.isDel(';')) break;
483  stat.append(token);
484 
485  if(token.isDel('(')) {
486  parseBracketList(')', stat);
487  } else if(token.isDel('[')) {
488  parseBracketList(']', stat);
489  } else if(token.isDel('{')) {
490  parseBracketList('}', stat);
491  }
492 
493  token = readToken();
494  }
495 }
496 
497 
499  if(inputStack.empty()) {
500  return Token("", 0, Token::IS_EOF, "End of input");
501  } else {
502  return inputStack.back()->readToken();
503  }
504 }
505 
506 
508  Statement *stat = 0;
509  Token token = is->readToken();
510 
511  try {
512  if(token.isDel('{')) {
513  // Compound statement.
514  inputStack.back()->putBack(token);
515  stat = new CompoundStatement(*inputStack.back());
516  } else if(token.isKey("IF")) {
517  // IF statement.
518  inputStack.back()->putBack(token);
519  stat = new IfStatement(*this, *inputStack.back());
520  } else if(token.isKey("WHILE")) {
521  // WHILE statement.
522  inputStack.back()->putBack(token);
523  stat = new WhileStatement(*this, *inputStack.back());
524  } else if(token.isWord() || token.isString()) {
525  // Simple statement or MACRO statement.
526  stat = new SimpleStatement(token.getFile(), token.getLine());
527  stat->append(token);
528  token = is->readToken();
529 
530  if(! token.isEOF()) {
531  if(token.isDel('(')) {
532  // Macro statement; statement already contains initial word.
533  stat->append(token);
534  parseBracketList(')', *stat);
535  token = is->readToken();
536 
537  if(! token.isEOF() && token.isDel(':')) {
538  // Macro definition.
539  stat->append(token);
540  token = is->readToken();
541 
542  if(! token.isEOF()) {
543  stat->append(token);
544  if(token.isKey("MACRO")) {
545  token = is->readToken();
546 
547  if(! token.isEOF() && token.isDel('{')) {
548  stat->append(token);
549  parseBracketList('}', *stat);
550  } else {
551  throw ParseError("OpalParser::readStatement()",
552  "MACRO definition lacks \"{...}\".");
553  }
554  } else {
555  parseTokenList(*stat);
556  }
557  }
558  } else if(! token.isDel(';')) {
559  throw ParseError("OpalParser::readStatement()",
560  "MACRO call is not terminated by ';'.");
561  }
562  } else if(! token.isDel(';')) {
563  stat->append(token);
564  parseTokenList(*stat);
565  }
566  }
567  stat->start();
568  } else if(token.isDel(';')) {
569  // Skip empty statement.
570  stat = readStatement(is);
571  } else if(token.isDel('?')) {
572  // Give help.
573  *gmsg << "\ntry typing \"HELP\" or \"SHOW\" for help.\n" << endl;
574  stat = readStatement(is);
575  } else if(! token.isEOF()) {
576  stat = new SimpleStatement(token.getFile(), token.getLine());
577  stat->append(token);
578  parseTokenList(*stat);
579  stat->start();
580  throw ParseError("OpalParser::readStatement()",
581  "Command should begin with a <name>.");
582  }
583  } catch(ParseError &ex) {
584  ERRORMSG("\n*** Parse error detected by function \""
585  << "OpalParser::readStatement()" << "\"\n");
586  stat->printWhere(*IpplInfo::Error, true);
587 
588  std::string what = ex.what();
589  boost::replace_all(what, "\n", "\n ");
590 
591  ERRORMSG(" " << *stat <<" a" << what << '\n' << endl);
592 
593  stat = readStatement(is);
594  exit(1);
595  }
596 
597  return stat;
598 }
599 
600 
601 void OpalParser::run() const {
602  stopFlag = false;
603  while(Statement *stat = readStatement(&*inputStack.back())) {
604  try {
605  // The dispatch via Statement::execute() allows a special
606  // treatment of structured statements.
607  stat->execute(*this);
608  } catch(ParseError &ex) {
609  Inform errorMsg("Error", std::cerr);
610  errorMsg << "\n*** Parse error detected by function \""
611  << ex.where() << "\"\n";
612  stat->printWhere(errorMsg, true);
613  std::string what = ex.what();
614  size_t pos = what.find_first_of('\n');
615  do {
616  errorMsg << " " << what.substr(0, pos) << endl;
617  what = what.substr(pos + 1, std::string::npos);
618  pos = what.find_first_of('\n');
619  } while (pos != std::string::npos);
620  errorMsg << " " << what << endl;
621 
622  MPI_Abort(MPI_COMM_WORLD, -100);
623  }
624 
625  delete stat;
626  if(stopFlag) break;
627  }
628 }
629 
630 void OpalParser::run(TokenStream *is) const {
631  inputStack.push_back(is);
632  run();
633  inputStack.pop_back();
634 }
635 
636 
637 void OpalParser::stop() const {
638  stopFlag = true;
639 }
640 
641 std::string OpalParser::getHint(const std::string &name, const std::string &type) {
642  auto owner = AttributeHandler::getOwner(name);
643  if (owner.size() > 0) {
644  std::string hint = "the " + type + " '" + name + "' could belong to\n";
645  {
646  std::string elements = "";
647  auto its = owner.equal_range(AttributeHandler::ELEMENT);
648  if (its.first != its.second) {
649  elements = (its.first)->second;
650  bool any = (its.first)->second == "Any";
651  for (auto it = std::next(its.first); it != its.second && !any; ++ it) {
652  elements += ", " + it->second;
653  any = it->second == "Any";
654  }
655  if (any) {
656  hint += std::string(" - any element\n");
657  } else {
658  hint += std::string(" - the element") + (std::distance(its.first, its.second) > 1? "s ": " ") + elements + "\n";
659  }
660  }
661  }
662  {
663  std::string commands = "";
664  auto its = owner.equal_range(AttributeHandler::COMMAND);
665  if (its.first != its.second) {
666  commands = (its.first)->second;
667  for (auto it = std::next(its.first); it != its.second; ++ it) {
668  commands += ", " + it->second;
669  }
670  hint += std::string(" - the command") + (std::distance(its.first, its.second) > 1? "s ": " ") + commands + "\n";
671  }
672  }
673  {
674  std::string sub_commands = "";
675  auto its = owner.equal_range(AttributeHandler::SUB_COMMAND);
676  if (its.first != its.second) {
677  sub_commands = (its.first)->second;
678  for (auto it = std::next(its.first); it != its.second; ++ it) {
679  sub_commands += ", " + it->second;
680  }
681  hint += std::string(" - the sub-command") + (std::distance(its.first, its.second) > 1? "s ": " ") + sub_commands + "\n";
682  }
683  }
684  {
685  std::string statements = "";
686  auto its = owner.equal_range(AttributeHandler::STATEMENT);
687  if (its.first != its.second) {
688  statements = (its.first)->second;
689  for (auto it = std::next(its.first); it != its.second; ++ it) {
690  statements += ", " + it->second;
691  }
692  hint += std::string(" - the statement") + (std::distance(its.first, its.second) > 1? "s ": " ") + statements + "\n";
693  }
694  }
695 
696  hint += "but it's not present!";
697  return hint;
698  }
699 
700  return "";
701 }
bool mtrace
Trace flag.
Definition: Options.cpp:29
double Round(double value)
Round the double argument.
Definition: Round.cpp:23
elements
Definition: IndexMap.cpp:141
bool isEOF() const
Test for end of file.
Definition: Token.cpp:107
double parseRealConst(Statement &)
Parse real constant.
bool keyword(const char *s)
Test for keyword.
Definition: Statement.cpp:123
Parse exception.
Definition: ParseError.h:32
void define(Object *newObject)
Define a new object.
Definition: OpalData.cpp:538
virtual void setShared(bool)
Set/reset shared flag.
Definition: Object.cpp:252
void mark()
Mark position in command.
Definition: Statement.cpp:172
void execute(Object *, const std::string &) const
Execute or check the current command.
Definition: OpalParser.cpp:125
virtual bool shouldUpdate() const =0
Update flag.
Abstract interface for a stream of input tokens.
Definition: TokenStream.h:33
bool stopFlag
Definition: OpalParser.h:116
virtual Attribute * findAttribute(const std::string &name)
Find an attribute by name.
virtual void parseMacro(const std::string &name, Statement &) const
Parse macro definition or call.
Definition: OpalParser.cpp:388
bool isWord() const
Test for word.
Definition: Token.cpp:127
#define ERRORMSG(msg)
Definition: IpplInfo.h:399
virtual bool shouldTrace() const =0
Trace flag.
static void parseTokenList(Statement &)
Definition: OpalParser.cpp:477
virtual Object * makeTemplate(const std::string &, TokenStream &, Statement &)
Macro handler function.
Definition: Object.cpp:88
bool atEnd() const
Test for end of command.
Definition: Statement.cpp:52
Inform * gmsg
Definition: Main.cpp:21
Compound statement.
void update()
Update all objects.
Definition: OpalData.cpp:723
void restore()
Return to marked position.
Definition: Statement.cpp:177
void stop() const
Set stop flag.
Definition: OpalParser.cpp:637
void parseDelimiter(Statement &stat, char delim)
Test for one-character delimiter.
static std::vector< Pointer< TokenStream > > inputStack
Definition: OpalParser.h:119
static OpalData * getInstance()
Definition: OpalData.cpp:209
const std::string & getLex() const
Return the lexeme.
Definition: Token.cpp:200
virtual Token readToken()=0
Read single token from stream.
A representation of an Object attribute.
Definition: Attribute.h:55
static std::string getHint(const std::string &, const std::string &="attribute")
Definition: OpalParser.cpp:641
Interface for statements.
Definition: Statement.h:38
virtual Statement * readStatement(TokenStream *) const
Read complete statement from a token stream.
Definition: OpalParser.cpp:507
While statement.
Representation of a single input token.
Definition: Token.h:33
virtual ~OpalParser()
Definition: OpalParser.cpp:61
virtual void printWhere(Inform &msg, bool withToken) const
Print position.
Definition: Statement.cpp:219
void start()
Return to start.
Definition: Statement.cpp:182
virtual Object * makeInstance(const std::string &name, Statement &, const Parser *)
Macro handler function.
Definition: Object.cpp:94
virtual void parseAssign(Statement &) const
Parse assignment statement.
Definition: OpalParser.cpp:191
static Token readToken()
Return next input token.
Definition: OpalParser.cpp:498
virtual const std::string & what() const
Return the message string for the exception.
virtual void print(std::ostream &os) const
Print statement.
Definition: Statement.cpp:206
static void parseBracketList(char close, Statement &)
Definition: OpalParser.cpp:456
void append(const Token &)
Append a token.
Definition: Statement.cpp:47
virtual void run() const
Read current stream.
Definition: OpalParser.cpp:601
static Inform * Error
Definition: IpplInfo.h:89
virtual void parseAction(Statement &) const
Parse executable command.
Definition: OpalParser.cpp:155
bool any(const PETE_Expr< T1 > &expr, T2 val)
virtual void printHelp(const std::string &) const
Print help on named command.
Definition: OpalParser.cpp:444
static std::multimap< OwnerType, std::string > getOwner(const std::string &att)
Object * find(const std::string &name)
Find entry.
Definition: OpalData.cpp:618
bool isString() const
Test for string.
Definition: Token.cpp:132
The base class for all OPAL objects.
Definition: Object.h:48
virtual void parseEnd(Statement &) const
Check for end of statement.
Definition: OpalParser.cpp:372
A simple input statement in token form.
virtual Object * clone(const std::string &name)=0
Return a clone.
const std::string name
If statement.
Definition: IfStatement.h:35
bool isKey(const char *key) const
Test for keyword.
Definition: Token.cpp:137
virtual void parseDefine(Statement &) const
Parse definition.
Definition: OpalParser.cpp:325
Token & getCurrent()
Return current token and skip it.
Definition: Statement.cpp:76
bool isDel(char del) const
Test for delimiter.
Definition: Token.cpp:92
virtual void parse(Statement &)
Parse the object.
Definition: Object.cpp:100
bool isTreeMember(const Object *subTree) const
Test for tree membership.
Definition: Object.cpp:294
std::string parseString(Statement &, const char msg[])
Parse string value.
bool delimiter(char c)
Test for delimiter.
Definition: Statement.cpp:103
Definition: Inform.h:41
virtual void parse(Statement &) const
Parse and execute current statement.
Definition: OpalParser.cpp:65
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
int getLine() const
Return the token&#39;s line number.
Definition: Token.cpp:215
void makeDirty(Object *object)
Invalidate expressions.
Definition: OpalData.cpp:629
virtual Object * find(const std::string &) const
Find object by name in the main directory.
Definition: OpalParser.cpp:150
const std::string & getFile() const
Return the token&#39;s file name.
Definition: Token.cpp:210
unsigned int position() const
Return current character number in line.
Definition: Statement.cpp:192
virtual const std::string & where() const
Return the name of the method or function which detected the exception.