44#include "Utility/Inform.h"
45#include "Utility/IpplInfo.h"
70 std::string name =
parseString(stat,
"Identifier or keyword expected.");
89 std::string objName =
parseString(stat,
"Object name expected.");
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;
102 "OpalParser::parse()",
103 statStr.str() + positionIndicator
104 +
"Syntax error, either the keyword REAL is missing or\n"
108 "OpalParser::parse()",
109 statStr.str() + positionIndicator
110 +
"Syntax error, the keyword REAL is missing\n");
121 double time = double(clock()) / double(CLOCKS_PER_SEC);
122 *
gmsg <<
"\nBegin execution: \"" << name <<
"\", CPU time = " << time <<
" seconds.\n"
136 double time = double(clock()) / double(CLOCKS_PER_SEC);
137 *
gmsg <<
"\nEnd execution: \"" << name <<
"\", CPU time = " << time <<
" seconds.\n"
148 std::string cmdName =
parseString(stat,
"Command name expected");
150 if (cmdName ==
"STOP") {
152 }
else if (cmdName ==
"QUIT") {
154 }
else if (cmdName ==
"HELP" && stat.
delimiter(
',')) {
155 cmdName =
parseString(stat,
"Object name expected");
160 copy =
object->
clone(
"");
170 std::string hint =
getHint(cmdName,
"command");
172 throw ParseError(
"OpalParser::parseAction()",
"Syntax error, " + hint);
175 throw ParseError(
"OpalParser::parseAction()",
"Command \"" + cmdName +
"\" is unknown.");
199 }
else if (stat.
keyword(
"BOOL")) {
201 }
else if (stat.
keyword(
"REAL")) {
203 }
else if (stat.
keyword(
"STRING")) {
205 }
else if (stat.
keyword(
"VECTOR")) {
212 std::string objName =
parseString(stat,
"Object name expected.");
215 std::string attrName;
219 attrName =
parseString(stat,
"Attribute name expected.");
223 "OpalParser::parseAssign()",
"Invalid type specification for this value.");
226 "OpalParser::parseAssign()",
"The object \"" + objName +
"\" is unknown.");
235 model = realConstant;
239 model = boolConstant;
243 model = realVariable;
253 model = stringConstant;
260 object = model->
clone(objName);
263 throw ParseError(
"OpalParser::parseAssign()",
"Invalid <type> field.");
267 "OpalParser::parseAssign()",
268 "You cannot redefine the constant \"" + objName +
"\".");
282 throw ParseError(
"Expressions::parseReference()",
"Index must be positive.");
290 attr->parseComponent(stat,
true, index);
292 attr->parse(stat,
true);
296 attr->parseComponent(stat,
false, index);
298 attr->parse(stat,
false);
303 "OpalParser::parseAssign()",
304 "Object \"" + objName +
"\" has no attribute \"" + attrName +
"\".");
314 bool isShared = stat.
keyword(
"SHARED");
315 std::string objName =
parseString(stat,
"Object name expected.");
318 std::string clsName =
parseString(stat,
"Class name expected.");
321 if (classObject == 0) {
322 if (clsName ==
"SURFACEPHYSICS")
324 "OpalParser::parseDefine()",
325 "The object \"" + clsName
326 +
"\" is changed to \"PARTICLEMATTERINTERACTION\".");
329 "OpalParser::parseDefine()",
"The object \"" + clsName +
"\" is unknown.");
339 copy = classObject->
clone(objName);
362 unsigned int position = stat.
position();
363 std::string positionIndicator = std::string(position + 1,
' ') +
"^\n";
364 std::ostringstream statStr;
368 "OpalParser::parseEnd()",
369 statStr.str() + positionIndicator
370 +
"Syntax error (maybe missing comma or semicolon ? )");
384 if (--par_level == 0)
break;
392 std::string className =
parseString(stat,
"Class name expected.");
402 "OpalParser::parseMacro()",
403 "Command \"" + macName +
"\" cannot be defined with arguments.");
407 "OpalParser::parseMacro()",
"Object \"" + className +
"\" is unknown.");
423 throw ParseError(
"OpalParser::parseMacro()",
"Macro \"" + macName +
"\" is unknown.");
432 *
gmsg <<
"\nOpalParser::printHelp(): Unknown object \"" << cmdName <<
"\".\n" << endl;
434 object->printHelp(std::cerr);
441 while (!token.
isEOF()) {
444 if (token.
isDel(
'(')) {
446 }
else if (token.
isDel(
'[')) {
448 }
else if (token.
isDel(
'{')) {
450 }
else if (token.
isDel(close)) {
461 while (!token.
isEOF()) {
463 if (token.
isDel(
';'))
break;
466 if (token.
isDel(
'(')) {
468 }
else if (token.
isDel(
'[')) {
470 }
else if (token.
isDel(
'{')) {
491 if (token.
isDel(
'{')) {
495 }
else if (token.
isKey(
"IF")) {
499 }
else if (token.
isKey(
"WHILE")) {
509 if (!token.
isEOF()) {
510 if (token.
isDel(
'(')) {
521 if (!token.
isEOF()) {
523 if (token.
isKey(
"MACRO")) {
531 "OpalParser::readStatement()",
532 "MACRO definition lacks \"{...}\".");
538 }
else if (!token.
isDel(
';')) {
540 "OpalParser::readStatement()",
541 "MACRO call is not terminated by ';'.");
543 }
else if (!token.
isDel(
';')) {
549 }
else if (token.
isDel(
';')) {
552 }
else if (token.
isDel(
'?')) {
554 *
gmsg <<
"\ntry typing \"HELP\" for help.\n" << endl;
556 }
else if (!token.
isEOF()) {
561 throw ParseError(
"OpalParser::readStatement()",
"Command should begin with a <name>.");
564 *ippl::Error <<
"\n*** Parse error detected by function \""
565 <<
"OpalParser::readStatement()"
569 std::string what = ex.
what();
570 std::string::size_type pos = 0;
571 while ((pos = what.find(
"\n", pos)) != std::string::npos) {
572 what.replace(pos, 1,
"\n ");
576 *ippl::Error <<
" " << *stat <<
" a" << what <<
'\n' << endl;
593 Inform errorMsg(
"Error", std::cerr);
594 errorMsg <<
"\n*** Parse error detected by function \"" << ex.
where() <<
"\"\n";
595 stat->printWhere(errorMsg,
true);
596 std::string what = ex.
what();
597 size_t pos = what.find_first_of(
'\n');
599 errorMsg <<
" " << what.substr(0, pos) << endl;
600 what = what.substr(pos + 1, std::string::npos);
601 pos = what.find_first_of(
'\n');
602 }
while (pos != std::string::npos);
603 errorMsg <<
" " << what << endl;
605 MPI_Abort(MPI_COMM_WORLD, -100);
614 inputStack.push_back(std::shared_ptr<TokenStream>(is));
624 return std::string();
627 std::string hint =
"the " + type +
" '" + name +
"' could belong to\n";
631 if (its.first != its.second) {
633 bool any = (its.first)->second ==
"Any";
634 for (
auto it = std::next(its.first); it != its.second && !any; ++it) {
636 any = it->second ==
"Any";
639 hint += std::string(
" - any element\n");
641 hint += std::string(
" - the element")
642 + (std::distance(its.first, its.second) > 1 ?
"s " :
" ") +
elements +
"\n";
647 std::string commands;
649 if (its.first != its.second) {
650 commands = (its.first)->second;
651 for (
auto it = std::next(its.first); it != its.second; ++it) {
652 commands +=
", " + it->second;
654 hint += std::string(
" - the command")
655 + (std::distance(its.first, its.second) > 1 ?
"s " :
" ") + commands +
"\n";
659 std::string sub_commands;
661 if (its.first != its.second) {
662 sub_commands = (its.first)->second;
663 for (
auto it = std::next(its.first); it != its.second; ++it) {
664 sub_commands +=
", " + it->second;
666 hint += std::string(
" - the sub-command")
667 + (std::distance(its.first, its.second) > 1 ?
"s " :
" ") + sub_commands +
"\n";
671 std::string statements;
673 if (its.first != its.second) {
674 statements = (its.first)->second;
675 for (
auto it = std::next(its.first); it != its.second; ++it) {
676 statements +=
", " + it->second;
678 hint += std::string(
" - the statement")
679 + (std::distance(its.first, its.second) > 1 ?
"s " :
" ") + statements +
"\n";
683 hint +=
"but it's not present!";
static std::multimap< OwnerType, std::string > getOwner(const std::string &att)
A representation of an Object attribute.
The base class for all OPAL objects.
virtual bool shouldTrace() const =0
Trace flag.
virtual Object * makeTemplate(const std::string &, TokenStream &, Statement &)
Macro handler function.
virtual Object * clone(const std::string &name)=0
Return a clone.
virtual Object * makeInstance(const std::string &name, Statement &, const Parser *)
Macro handler function.
virtual void setShared(bool)
Set/reset shared flag.
virtual Attribute * findAttribute(const std::string &name)
Find an attribute by name.
virtual bool shouldUpdate() const =0
Update flag.
bool isTreeMember(const Object *subTree) const
Test for tree membership.
virtual void parse(Statement &)
Parse the object.
void makeDirty(Object *object)
Invalidate expressions.
void update()
Update all objects.
Object * find(const std::string &name)
Find entry.
static OpalData * getInstance()
void define(Object *newObject)
Define a new object.
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.
virtual void parseAssign(Statement &) const
Parse assignment statement.
static Token readToken()
Return next input token.
static void parseTokenList(Statement &)
static std::vector< std::shared_ptr< TokenStream > > inputStack
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 &)
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 void parseDefine(Statement &) const
Parse definition.
virtual void parseAction(Statement &) const
Parse executable command.
A simple input statement in token form.
Interface for statements.
Token & getCurrent()
Return current token and skip it.
void append(const Token &)
Append a token.
unsigned int position() const
Return current character number in line.
void restore()
Return to marked 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.
bool delimiter(char c)
Test for delimiter.
void start()
Return to start.
Abstract interface for a stream of input tokens.
virtual Token readToken()=0
Read single token from stream.
Representation of a single input token.
bool isString() const
Test for string.
bool isDel(char del) const
Test for delimiter.
bool isWord() const
Test for word.
bool isEOF() const
Test for end of file.
const std::string & getLex() const
Return the lexeme.
bool isKey(const char *key) const
Test for keyword.
int getLine() const
Return the token's line number.
const std::string & getFile() const
Return the token's file name.
Representation objects and parsers for attribute expressions.
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.