43 #include <boost/algorithm/string.hpp>
47 using namespace Expressions;
75 std::string
name =
parseString(stat,
"Identifier or keyword expected.");
95 std::string objName =
parseString(stat,
"Object name expected.");
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;
110 "Syntax error, either the keyword REAL is missing or\n" +
116 "Syntax error, the keyword REAL is missing\n");
128 double time = double(clock()) / double(CLOCKS_PER_SEC);
129 *
gmsg <<
"\nBegin execution: \"" << name
130 <<
"\", CPU time = " << time <<
" seconds.\n" <<
endl;
143 double time = double(clock()) / double(CLOCKS_PER_SEC);
144 *
gmsg <<
"\nEnd execution: \"" << name
145 <<
"\", CPU time = " << time <<
" seconds.\n" <<
endl;
157 std::string cmdName =
parseString(stat,
"Command name expected");
159 if(cmdName ==
"STOP") {
161 }
else if(cmdName ==
"QUIT") {
163 }
else if(cmdName ==
"HELP" && stat.
delimiter(
',')) {
164 cmdName =
parseString(stat,
"Object name expected");
169 copy =
object->
clone(
"");
179 std::string hint =
getHint(cmdName,
"command");
182 "Syntax error, " + hint);
186 "Command \"" + cmdName +
"\" is unknown.");
211 }
else if(stat.
keyword(
"BOOL")) {
213 }
else if(stat.
keyword(
"REAL")) {
215 }
else if(stat.
keyword(
"STRING")) {
217 }
else if(stat.
keyword(
"VECTOR")) {
224 std::string objName =
parseString(stat,
"Object name expected.");
227 std::string attrName;
231 attrName =
parseString(stat,
"Attribute name expected.");
235 "Invalid type specification for this value.");
238 "The object \"" + objName +
"\" is unknown.");
247 model = realConstant;
251 model = boolConstant;
255 model = realVariable;
265 model = stringConstant;
272 object = model->
clone(objName);
275 throw ParseError(
"OpalParser::parseAssign()",
"Invalid <type> field.");
279 "You cannot redefine the constant \"" + objName +
"\".");
293 throw ParseError(
"Expressions::parseReference()",
294 "Index must be positive.");
300 if(stat.
delimiter(
'=') ||
object->isTreeMember(realConstant)) {
302 attr->parseComponent(stat,
true, index);
304 attr->parse(stat,
true);
308 attr->parseComponent(stat,
false, index);
310 attr->parse(stat,
false);
315 "Object \"" + objName +
"\" has no attribute \"" +
327 bool isShared = stat.
keyword(
"SHARED");
328 std::string objName =
parseString(stat,
"Object name expected.");
331 std::string clsName =
parseString(stat,
"Class name expected.");
334 if(classObject == 0) {
335 if (clsName ==
"SURFACEPHYSICS")
337 "The object \"" + clsName +
"\" is changed to \"PARTICLEMATTERINTERACTION\".");
340 "The object \"" + clsName +
"\" is unknown.");
350 copy = classObject->
clone(objName);
375 unsigned int position = stat.
position();
376 std::string positionIndicator = std::string(position + 1,
' ') +
"^\n";
377 std::ostringstream statStr;
383 "Syntax error (maybe missing comma or semicolon ? )");
398 if(--par_level == 0)
break;
406 std::string className =
parseString(stat,
"Class name expected.");
416 throw ParseError(
"OpalParser::parseMacro()",
"Command \"" +
417 macName +
"\" cannot be defined with arguments.");
421 "Object \"" + className +
"\" is unknown.");
438 "Macro \"" + macName +
"\" is unknown.");
448 *
gmsg <<
"\nOpalParser::printHelp(): Unknown object \""
449 << cmdName <<
"\".\n" <<
endl;
451 object->printHelp(std::cerr);
459 while(! token.
isEOF()) {
462 if(token.
isDel(
'(')) {
464 }
else if(token.
isDel(
'[')) {
466 }
else if(token.
isDel(
'{')) {
468 }
else if(token.
isDel(close)) {
480 while(! token.
isEOF()) {
482 if(token.
isDel(
';'))
break;
485 if(token.
isDel(
'(')) {
487 }
else if(token.
isDel(
'[')) {
489 }
else if(token.
isDel(
'{')) {
512 if(token.
isDel(
'{')) {
516 }
else if(token.
isKey(
"IF")) {
520 }
else if(token.
isKey(
"WHILE")) {
530 if(! token.
isEOF()) {
531 if(token.
isDel(
'(')) {
542 if(! token.
isEOF()) {
544 if(token.
isKey(
"MACRO")) {
551 throw ParseError(
"OpalParser::readStatement()",
552 "MACRO definition lacks \"{...}\".");
558 }
else if(! token.
isDel(
';')) {
559 throw ParseError(
"OpalParser::readStatement()",
560 "MACRO call is not terminated by ';'.");
562 }
else if(! token.
isDel(
';')) {
568 }
else if(token.
isDel(
';')) {
571 }
else if(token.
isDel(
'?')) {
573 *
gmsg <<
"\ntry typing \"HELP\" or \"SHOW\" for help.\n" <<
endl;
575 }
else if(! token.
isEOF()) {
580 throw ParseError(
"OpalParser::readStatement()",
581 "Command should begin with a <name>.");
584 ERRORMSG(
"\n*** Parse error detected by function \""
585 <<
"OpalParser::readStatement()" <<
"\"\n");
588 std::string what = ex.
what();
589 boost::replace_all(what,
"\n",
"\n ");
607 stat->execute(*
this);
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');
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;
622 MPI_Abort(MPI_COMM_WORLD, -100);
643 if (owner.size() > 0) {
644 std::string hint =
"the " + type +
" '" + name +
"' could belong to\n";
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";
656 hint += std::string(
" - any element\n");
658 hint += std::string(
" - the element") + (std::distance(its.first, its.second) > 1?
"s ":
" ") + elements +
"\n";
663 std::string commands =
"";
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;
670 hint += std::string(
" - the command") + (std::distance(its.first, its.second) > 1?
"s ":
" ") + commands +
"\n";
674 std::string sub_commands =
"";
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;
681 hint += std::string(
" - the sub-command") + (std::distance(its.first, its.second) > 1?
"s ":
" ") + sub_commands +
"\n";
685 std::string statements =
"";
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;
692 hint += std::string(
" - the statement") + (std::distance(its.first, its.second) > 1?
"s ":
" ") + statements +
"\n";
696 hint +=
"but it's not present!";
double Round(double value)
Round the double argument.
bool isEOF() const
Test for end of file.
double parseRealConst(Statement &)
Parse real constant.
bool keyword(const char *s)
Test for keyword.
void define(Object *newObject)
Define a new object.
virtual void setShared(bool)
Set/reset shared flag.
void mark()
Mark position in command.
void execute(Object *, const std::string &) const
Execute or check the current command.
virtual bool shouldUpdate() const =0
Update flag.
Abstract interface for a stream of input tokens.
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.
bool isWord() const
Test for word.
virtual bool shouldTrace() const =0
Trace flag.
static void parseTokenList(Statement &)
virtual Object * makeTemplate(const std::string &, TokenStream &, Statement &)
Macro handler function.
bool atEnd() const
Test for end of command.
void update()
Update all objects.
void restore()
Return to marked position.
void stop() const
Set stop flag.
void parseDelimiter(Statement &stat, char delim)
Test for one-character delimiter.
static std::vector< Pointer< TokenStream > > inputStack
static OpalData * getInstance()
const std::string & getLex() const
Return the lexeme.
virtual Token readToken()=0
Read single token from stream.
A representation of an Object attribute.
static std::string getHint(const std::string &, const std::string &="attribute")
Interface for statements.
virtual Statement * readStatement(TokenStream *) const
Read complete statement from a token stream.
Representation of a single input token.
virtual void printWhere(Inform &msg, bool withToken) const
Print position.
void start()
Return to start.
virtual Object * makeInstance(const std::string &name, Statement &, const Parser *)
Macro handler function.
virtual void parseAssign(Statement &) const
Parse assignment statement.
static Token readToken()
Return next input token.
virtual const std::string & what() const
Return the message string for the exception.
virtual void print(std::ostream &os) const
Print statement.
static void parseBracketList(char close, Statement &)
void append(const Token &)
Append a token.
virtual void run() const
Read current stream.
virtual void parseAction(Statement &) const
Parse executable command.
bool any(const PETE_Expr< T1 > &expr, T2 val)
virtual void printHelp(const std::string &) const
Print help on named command.
static std::multimap< OwnerType, std::string > getOwner(const std::string &att)
Object * find(const std::string &name)
Find entry.
bool isString() const
Test for string.
The base class for all OPAL objects.
virtual void parseEnd(Statement &) const
Check for end of statement.
A simple input statement in token form.
virtual Object * clone(const std::string &name)=0
Return a clone.
bool isKey(const char *key) const
Test for keyword.
virtual void parseDefine(Statement &) const
Parse definition.
Token & getCurrent()
Return current token and skip it.
bool isDel(char del) const
Test for delimiter.
virtual void parse(Statement &)
Parse the object.
bool isTreeMember(const Object *subTree) const
Test for tree membership.
std::string parseString(Statement &, const char msg[])
Parse string value.
bool delimiter(char c)
Test for delimiter.
virtual void parse(Statement &) const
Parse and execute current statement.
Inform & endl(Inform &inf)
int getLine() const
Return the token's line number.
void makeDirty(Object *object)
Invalidate expressions.
virtual Object * find(const std::string &) const
Find object by name in the main directory.
const std::string & getFile() const
Return the token's file name.
unsigned int position() const
Return current character number in line.
virtual const std::string & where() const
Return the name of the method or function which detected the exception.