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