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