OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
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 != "") {
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 != "") {
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)) {
415  OpalData::getInstance()->define(copy);
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 
631 void OpalParser::run(TokenStream *is) const {
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.size() > 0) {
645  std::string hint = "the " + type + " '" + name + "' could belong to\n";
646  {
647  std::string elements = "";
648  auto its = owner.equal_range(AttributeHandler::ELEMENT);
649  if (its.first != its.second) {
650  elements = (its.first)->second;
651  bool any = (its.first)->second == "Any";
652  for (auto it = std::next(its.first); it != its.second && !any; ++ it) {
653  elements += ", " + it->second;
654  any = it->second == "Any";
655  }
656  if (any) {
657  hint += std::string(" - any element\n");
658  } else {
659  hint += std::string(" - the element") + (std::distance(its.first, its.second) > 1? "s ": " ") + elements + "\n";
660  }
661  }
662  }
663  {
664  std::string commands = "";
665  auto its = owner.equal_range(AttributeHandler::COMMAND);
666  if (its.first != its.second) {
667  commands = (its.first)->second;
668  for (auto it = std::next(its.first); it != its.second; ++ it) {
669  commands += ", " + it->second;
670  }
671  hint += std::string(" - the command") + (std::distance(its.first, its.second) > 1? "s ": " ") + commands + "\n";
672  }
673  }
674  {
675  std::string sub_commands = "";
676  auto its = owner.equal_range(AttributeHandler::SUB_COMMAND);
677  if (its.first != its.second) {
678  sub_commands = (its.first)->second;
679  for (auto it = std::next(its.first); it != its.second; ++ it) {
680  sub_commands += ", " + it->second;
681  }
682  hint += std::string(" - the sub-command") + (std::distance(its.first, its.second) > 1? "s ": " ") + sub_commands + "\n";
683  }
684  }
685  {
686  std::string statements = "";
687  auto its = owner.equal_range(AttributeHandler::STATEMENT);
688  if (its.first != its.second) {
689  statements = (its.first)->second;
690  for (auto it = std::next(its.first); it != its.second; ++ it) {
691  statements += ", " + it->second;
692  }
693  hint += std::string(" - the statement") + (std::distance(its.first, its.second) > 1? "s ": " ") + statements + "\n";
694  }
695  }
696 
697  hint += "but it's not present!";
698  return hint;
699  }
700 
701  return "";
702 }
elements
Definition: IndexMap.cpp:163
Inform * gmsg
Definition: Main.cpp:62
bool any(const PETE_Expr< T1 > &expr, T2 val)
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
const std::string name
Representation objects and parsers for attribute expressions.
Definition: Expressions.h:64
std::string parseString(Statement &, const char msg[])
Parse string value.
void parseDelimiter(Statement &stat, char delim)
Test for one-character delimiter.
double parseRealConst(Statement &)
Parse real constant.
bool mtrace
Trace flag.
Definition: Options.cpp:31
boost::function< boost::tuple< double, bool >arguments_t)> type
Definition: function.hpp:21
A representation of an Object attribute.
Definition: Attribute.h:52
static std::multimap< OwnerType, std::string > getOwner(const std::string &att)
The base class for all OPAL objects.
Definition: Object.h:48
virtual bool shouldTrace() const =0
Trace flag.
virtual Object * makeTemplate(const std::string &, TokenStream &, Statement &)
Macro handler function.
Definition: Object.cpp:85
virtual Object * makeInstance(const std::string &name, Statement &, const Parser *)
Macro handler function.
Definition: Object.cpp:91
virtual Object * clone(const std::string &name)=0
Return a clone.
virtual void setShared(bool)
Set/reset shared flag.
Definition: Object.cpp:249
virtual Attribute * findAttribute(const std::string &name)
Find an attribute by name.
Definition: Object.cpp:64
virtual bool shouldUpdate() const =0
Update flag.
bool isTreeMember(const Object *subTree) const
Test for tree membership.
Definition: Object.cpp:291
virtual void parse(Statement &)
Parse the object.
Definition: Object.cpp:97
void makeDirty(Object *object)
Invalidate expressions.
Definition: OpalData.cpp:574
void update()
Update all objects.
Definition: OpalData.cpp:674
Object * find(const std::string &name)
Find entry.
Definition: OpalData.cpp:565
static OpalData * getInstance()
Definition: OpalData.cpp:195
void define(Object *newObject)
Define a new object.
Definition: OpalData.cpp:488
A simple input statement in token form.
Interface for statements.
Definition: Statement.h:38
Token & getCurrent()
Return current token and skip it.
Definition: Statement.cpp:74
void append(const Token &)
Append a token.
Definition: Statement.cpp:45
unsigned int position() const
Return current character number in line.
Definition: Statement.cpp:190
void restore()
Return to marked position.
Definition: Statement.cpp:175
virtual void printWhere(Inform &msg, bool withToken) const
Print position.
Definition: Statement.cpp:217
bool keyword(const char *s)
Test for keyword.
Definition: Statement.cpp:121
void mark()
Mark position in command.
Definition: Statement.cpp:170
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
bool delimiter(char c)
Test for delimiter.
Definition: Statement.cpp:101
void start()
Return to start.
Definition: Statement.cpp:180
Representation of a single input token.
Definition: Token.h:33
bool isString() const
Test for string.
Definition: Token.cpp:132
bool isDel(char del) const
Test for delimiter.
Definition: Token.cpp:92
bool isWord() const
Test for word.
Definition: Token.cpp:127
bool isEOF() const
Test for end of file.
Definition: Token.cpp:107
const std::string & getLex() const
Return the lexeme.
Definition: Token.cpp:200
bool isKey(const char *key) const
Test for keyword.
Definition: Token.cpp:137
int getLine() const
Return the token's line number.
Definition: Token.cpp:215
@ IS_EOF
Definition: Token.h:40
const std::string & getFile() const
Return the token's file name.
Definition: Token.cpp:210
Abstract interface for a stream of input tokens.
Definition: TokenStream.h:33
virtual Token readToken()=0
Read single token from stream.
virtual const std::string & what() const
Return the message string for the exception.
virtual const std::string & where() const
Return the name of the method or function which detected the exception.
Parse exception.
Definition: ParseError.h:32
Compound statement.
If statement.
Definition: IfStatement.h:35
bool stopFlag
Definition: OpalParser.h:116
virtual void parseAssign(Statement &) const
Parse assignment statement.
Definition: OpalParser.cpp:192
static Token readToken()
Return next input token.
Definition: OpalParser.cpp:499
static void parseTokenList(Statement &)
Definition: OpalParser.cpp:478
virtual void parseEnd(Statement &) const
Check for end of statement.
Definition: OpalParser.cpp:373
virtual void run() const
Read current stream.
Definition: OpalParser.cpp:602
virtual Object * find(const std::string &) const
Find object by name in the main directory.
Definition: OpalParser.cpp:151
virtual void parseMacro(const std::string &name, Statement &) const
Parse macro definition or call.
Definition: OpalParser.cpp:389
static void parseBracketList(char close, Statement &)
Definition: OpalParser.cpp:457
static std::vector< Pointer< TokenStream > > inputStack
Definition: OpalParser.h:119
virtual Statement * readStatement(TokenStream *) const
Read complete statement from a token stream.
Definition: OpalParser.cpp:508
virtual void printHelp(const std::string &) const
Print help on named command.
Definition: OpalParser.cpp:445
void execute(Object *, const std::string &) const
Execute or check the current command.
Definition: OpalParser.cpp:126
static std::string getHint(const std::string &, const std::string &="attribute")
Definition: OpalParser.cpp:642
virtual void parse(Statement &) const
Parse and execute current statement.
Definition: OpalParser.cpp:66
void stop() const
Set stop flag.
Definition: OpalParser.cpp:638
virtual ~OpalParser()
Definition: OpalParser.cpp:62
virtual void parseDefine(Statement &) const
Parse definition.
Definition: OpalParser.cpp:326
virtual void parseAction(Statement &) const
Parse executable command.
Definition: OpalParser.cpp:156
While statement.
Definition: Inform.h:42
static Inform * Error
Definition: IpplInfo.h:80