/** * Initialize extra help functions */ void RevLanguage::Workspace::initializeExtraHelp(void) { try { // add the help entry for this type to the global help system instance // MonteCarloAnalysis mca; // RevBayesCore::RbHelpSystem::getHelpSystem().addHelpType( static_cast<RevBayesCore::RbHelpType*>(mca.getHelpEntry()) ); TimeTree tt; RevBayesCore::RbHelpSystem::getHelpSystem().addHelpType( static_cast<RevBayesCore::RbHelpType*>(tt.getHelpEntry()) ); } catch(RbException& rbException) { RBOUT("Caught an exception while initializing the help system\n"); std::ostringstream msg; rbException.print(msg); msg << std::endl; RBOUT(msg.str()); RBOUT("Please report this bug to the RevBayes Development Core Team"); RBOUT("Press any character to exit the program."); getchar(); exit(1); } }
/** This function gets help info about a symbol */ int RevLanguage::Parser::help(const std::string& baseSymbol, const std::string& symbol) const { std::ostringstream msg; // Get some help RevBayesCore::RbHelpSystem& hs = RevBayesCore::RbHelpSystem::getHelpSystem(); if ( hs.isHelpAvailableForQuery( baseSymbol, symbol) ) { const RevBayesCore::RbHelpEntry& h = hs.getHelp( baseSymbol, symbol ); RevBayesCore::HelpRenderer hRenderer; std::string hStr = hRenderer.renderHelp(h, RbSettings::userSettings().getLineWidth() - RevBayesCore::RbUtils::PAD.size()); UserInterface::userInterface().output("\n", true); UserInterface::userInterface().output("\n", true); UserInterface::userInterface().output(hStr, true); } else { RBOUT("Help is not available for \"" + baseSymbol + "." + symbol + "\""); } // Return success return 0; }
/** This function gets help info about a symbol */ int RevLanguage::Parser::help(const std::string& symbol) const { std::ostringstream msg; # if defined DEBUG_PARSER // Print syntax tree std::cerr << std::endl; std::cerr << "Parser trying to get help for symbol '" << symbol << "'"; std::cerr << std::endl; # endif // Get some help RevBayesCore::RbHelpSystem& hs = RevBayesCore::RbHelpSystem::getHelpSystem(); if ( hs.isHelpAvailableForQuery(symbol) ) { const RevBayesCore::RbHelpEntry& h = hs.getHelp( symbol ); RevBayesCore::HelpRenderer hRenderer; std::string hStr = hRenderer.renderHelp(h, RbSettings::userSettings().getLineWidth() - RevBayesCore::RbUtils::PAD.size()); UserInterface::userInterface().output("\n", true); UserInterface::userInterface().output("\n", true); UserInterface::userInterface().output(hStr, true); } else { RBOUT("Help is not available for \"" + symbol + "\""); } // Return success return 0; }
/** Loads (parses) the xml help file into the pugi::doc*/ pugi::xml_parse_result Help::loadHelpFile(const std::string& qs) { // the help file should be all lowercase if to be found std::string command = qs; std::transform(command.begin(), command.end(), command.begin(), ::tolower); std::string helpfile = this->helpDir + command + ".xml"; // try to load the corresponding xml file pugi::xml_parse_result result = doc.load_file(helpfile.c_str(), pugi::parse_default); if (result.status != pugi::status_ok) { RBOUT(result.description()); } return result; }
/** Initialize the help from an XML file */ void Help::initializeHelp(std::string helpDir) { // find the path to the directory containing the help files RevBayesCore::RbFileManager fMngr = RevBayesCore::RbFileManager(); //pathToHelpDir = fMngr.getCurrentDirectory(); fMngr.setFilePath(this->helpDir); if (fMngr.testDirectory() == false) { RBOUT("Warning: Cannot find directory containing help files. User help is unavailable. Path = " + this->helpDir); return; } }
/** * Process command buffer with the help of the bison-generated code. * * @param command command RlString; modified to contain any unprocessed incomplete statement residue, "" if none * @return integer flag indicating status: * 1 - (last) statement in command buffer is incomplete * 2 - syntax error encountered * 0 - all statements in command buffer syntactically correct, complete and executed * * @note If an exception occurs on execution of a syntactically correct * statement, the exception msg is printed here and the return * signal is set to 2. Any remaining part of the command buffer * is discarded. */ int RevLanguage::Parser::processCommand(std::string& command, Environment* env) { // make sure mode is not checking this->setParserMode(EXECUTING); // extern Environment* executionEnvironment; executionEnvironment = env; #ifdef DEBUG_PARSER std::cerr << "Processing command ... " << std::endl; #endif // Break command into Rev lines std::list<std::string> lines; try { breakIntoLines(command, lines, true); } catch (RbException& rbException) { #ifdef DEBUG_PARSER printf("Caught an exception while breaking command buffer into lines\n"); #endif // Print message std::ostringstream msg; rbException.print(msg); msg << std::endl; RBOUT(msg.str()); // We printed a message so we dealt with the problem // We exit immediately, discarding any command buffer content // We return 2 to signal a problem, which the caller may choose to ignore or act upon command = ""; return 2; } // Initialize flex column count yycolumn = 1; // Call Bison code, which calls Flex code, which calls rrinput for (std::list<std::string>::iterator i = lines.begin(); i != lines.end(); i++) { /* prepare globals for call to parser */ rrcommand.str((*i)); rrcommand.clear(); foundNewline = false; foundEOF = false; foundErrorBeforeEnd = false; #if 0 // NOTE! This code is only for testing the CHECKING mode of the parser // DO NOT UNCOMMENT IN NORMAL USE /* Set parser mode into checking */ setParserMode(CHECKING); #endif #ifdef DEBUG_PARSER printf("\nCalling bison with rrcommand:\n'%s'\n", rrcommand.str().c_str()); #endif int result; try { result = yyparse(); } catch (RbException& rbException) { #ifdef DEBUG_PARSER printf("Caught an exception\n"); #endif // Catch a quit request in case it was not caught before if (rbException.getExceptionType() == RbException::QUIT) { #ifdef RB_MPI MPI::Finalize(); #endif exit(0); } // All other uncaught exceptions #ifdef DEBUG_PARSER printf("Abnormal exception during parsing or execution of statement; discarding any remaining command buffer\n"); #endif // std::ostringstream msg; // rbException.print(msg); // msg << std::endl; // RBOUT(msg.str()); rbException.print(std::cerr); std::cerr << std::endl; // We exit immediately, discarding any remaining buffer content // We return 2 to signal a problem, which the caller may choose to ignore or act upon command = ""; return 2; } #if 0 // NOTE! This code is only for testing the CHECKING mode of the parser // DO NOT UNCOMMENT IN NORMAL USE if (result == 1) { std::cerr << "Function name is: " << functionName << std::endl; std::cerr << "Argument label is: " << argumentLabel << std::endl; if (baseVariable == NULL) std::cerr << "No base variable" << std::endl; else std::cerr << "Base variable is: " << baseVariable->getName() << std::endl; } #endif if (result == 0) { #ifdef DEBUG_PARSER printf("Parser successfully executed statement\n\n"); #endif } else if (result == 2) { // The execute function printed the error message resulting from the exception // We exit immediately, discarding any remaining buffer content // We return 2 to signal a problem, which the caller may choose to ignore or act upon command = ""; return 2; } else if (foundErrorBeforeEnd == true) { #ifdef DEBUG_PARSER printf("Syntax error detected by parser\n"); printf("Parser discarding any remaining parts of command buffer\n\n"); #endif std::ostringstream msg; if (yylloc.first_column == yylloc.last_column) { msg << "Syntax error while reading character '" << command[size_t(yylloc.first_column - 1)] << "' at position " << yylloc.first_column << " in command:" << std::endl; } else { msg << "Syntax error while reading characters \""; for (int j = yylloc.first_column; j <= yylloc.last_column; ++j) { msg << command[size_t(j - 1)]; } msg << "\" at position " << yylloc.first_column << " to " << yylloc.last_column << " in command:" << std::endl; } msg << command; RBOUT(msg.str()); command = ""; return 2; } else if (foundNewline == true && foundEOF == false) { #ifdef DEBUG_PARSER printf("Incomplete statement ending with inappropriate newline; replaced with space\n"); #endif /* Replace newline with space */ std::string temp = (*i); temp[temp.size() - 1] = ' '; std::list<std::string>::iterator j = i; j++; if (j == lines.end()) { /* If no more input lines, we need to ask for more */ #ifdef DEBUG_PARSER printf("Reached end; asking for more content to append to (last) statement.\n\n"); #endif command = temp; return 1; } else { /* If more input lines, put temp in front before proceeding */ #ifdef DEBUG_PARSER printf("Continuing with next Rev line in command buffer.\n\n"); #endif (*j) = temp + (*j); } } else if (foundNewline == true && foundEOF == true) { #ifdef DEBUG_PARSER printf("Incomplete statement ending with appropriate newline.\n"); #endif std::list<std::string>::iterator j = i; j++; if (j == lines.end()) { /* If no more input lines, we need to ask for more */ #ifdef DEBUG_PARSER printf("Reached end; asking for more content to append to (last) statement.\n\n"); #endif command = (*i); return 1; } else { /* If more input lines, put current line in front before proceeding */ #ifdef DEBUG_PARSER printf("Continuing with next Rev line in command buffer.\n\n"); #endif (*j) = (*i) + (*j); } } else { #ifdef DEBUG_PARSER printf("Unknown parse error\n"); #endif RBOUT("Unknown parse error"); command = ""; return 2; } } /* Successfully processed all statements in command buffer */ command = ""; return 0; }
/** * This function causes recursive execution of a syntax tree by calling the root to get its value. * As long as we return to the bison code, bison takes care of deleting the syntax tree. However, * if we encounter a quit() call, we delete the syntax tree ourselves and exit immediately. */ int RevLanguage::Parser::execute(SyntaxElement* root, Environment &env) const { // don't execute command if we are in checking mode if (RevLanguage::Parser::getParser().isChecking()) { #ifdef DEBUG_PARSER std::cerr << "Command is not executed since parser is set checking mode."; #endif return 0; } #ifdef DEBUG_PARSER // Print syntax tree std::cerr << std::endl; std::cerr << "Syntax tree root before execution:\n"; root->printValue(std::cerr); std::cerr << std::endl; #endif // Declare a variable for the result RevPtr<RevVariable> result = NULL; //! Execute syntax tree try { #ifdef DEBUG_PARSER printf("Parser getting the semantic value of the syntax tree...\n"); #endif result = root->evaluateContent(env); } catch (RbException& rbException) { std::ostringstream msg; // Catch a quit request if (rbException.getExceptionType() == RbException::QUIT) { delete( root); #ifdef RB_MPI MPI::Finalize(); #endif exit(0); } // Catch a missing variable exception that might be interpreted as a request for // usage help on a function SyntaxVariable* rootPtr = dynamic_cast<SyntaxVariable*> ((SyntaxElement*) root); SyntaxVariable* theVariable = rootPtr; if (rbException.getExceptionType() == RbException::MISSING_VARIABLE && theVariable != NULL) { const std::string& fxnName = theVariable->getIdentifier(); const std::vector<Function*>& functions = Workspace::userWorkspace().getFunctionTable().findFunctions(fxnName); if (functions.size() != 0) { for (std::vector<Function*>::const_iterator i = functions.begin(); i != functions.end(); i++) { std::ostringstream s; (*i)->printValue(s); RBOUT(s.str()); // Uncommenting this as the function callSignature() does not produce the call signature despite its name // -- Fredrik // RBOUT( (*i)->callSignature() ); } return 0; } } // All other exceptions #ifdef DEBUG_PARSER printf("Caught an exception\n"); #endif rbException.print(msg); RBOUT(msg.str()); // Return signal indicating problem return 2; } // Print result if the root is not an assign expression if (!root->isAssignment() && result != NULL && result->getRevObject() != RevNullObject::getInstance()) { std::ostringstream msg; result->getRevObject().printValue(msg,true); RBOUT(msg.str()); } // Warn if a return signal has been encountered // @todo Find out why the following lines do not work; they should // if ( Signals::getSignals().isSet( Signals::RETURN ) ) // RBOUT( "WARNING: No function to return from" ); Signals::getSignals().clearFlags(); // Return success return 0; }
/** Initialize global workspace */ void RevLanguage::Workspace::initializeTypeGlobalWorkspace(void) { try { AddWorkspaceVectorType<Taxon,4>::addTypeToWorkspace( *this, new Taxon() ); AddWorkspaceVectorType<RateGenerator,3>::addTypeToWorkspace( *this, new RateGenerator() ); AddWorkspaceVectorType<CladogeneticProbabilityMatrix,3>::addTypeToWorkspace( *this, new CladogeneticProbabilityMatrix() ); AddWorkspaceVectorType<MatrixReal,3>::addTypeToWorkspace( *this, new MatrixReal() ); AddWorkspaceVectorType<MatrixRealSymmetric,3>::addTypeToWorkspace( *this, new MatrixRealSymmetric() ); AddWorkspaceVectorType<AbstractHomologousDiscreteCharacterData,3>::addTypeToWorkspace( *this, new AbstractHomologousDiscreteCharacterData() ); AddWorkspaceVectorType<TimeTree,3>::addTypeToWorkspace( *this, new TimeTree() ); AddWorkspaceVectorType<BranchLengthTree,3>::addTypeToWorkspace( *this, new BranchLengthTree() ); AddWorkspaceVectorType<Tree,3>::addTypeToWorkspace( *this, new Tree() ); AddWorkspaceVectorType<Clade,3>::addTypeToWorkspace( *this, new Clade() ); // AddWorkspaceVectorType<AbstractModelObject,2>::addTypeToWorkspace( *this, NULL ); // addFunction( new Func_workspaceVector<AbstractModelObject>() ); addFunction( new Func_workspaceVector<AncestralStateTrace>() ); // AddVectorizedWorkspaceType<Monitor,3>::addTypeToWorkspace( *this, new Monitor() ); addFunction( new Func_workspaceVector<Monitor>() ); // AddVectorizedWorkspaceType<Move,3>::addTypeToWorkspace( *this, new Move() ); addFunction( new Func_workspaceVector<Move>() ); addFunction( new Func_workspaceVector<StoppingRule>() ); /* Add evolution types (in folder "datatypes/evolution") (alphabetic order) */ /* Add character types (in folder "datatypes/evolution/character") (alphabetic order) */ /* Add data matrix types (in folder "datatypes/evolution/datamatrix") (alphabetic order) */ /* Add tree types (in folder "datatypes/evolution/trees") (alphabetic order) */ addTypeWithConstructor( new Clade() ); // addTypeWithConstructor( "rootedTripletDist", new RootedTripletDistribution() ); /* Add Taxon (in folder "datatypes/evolution/") (alphabetic order) */ addTypeWithConstructor( new Taxon() ); /* Add math types (in folder "datatypes/math") */ addTypeWithConstructor( new CorrespondenceAnalysis() ); addType( new RateMap() ); // addType( new MatrixReal() ); /* Add inference types (in folder "datatypes/inference") (alphabetic order) */ addTypeWithConstructor( new BootstrapAnalysis() ); addTypeWithConstructor( new BurninEstimationConvergenceAssessment() ); addTypeWithConstructor( new HillClimber() ); addTypeWithConstructor( new Mcmc() ); addTypeWithConstructor( new Mcmcmc() ); addTypeWithConstructor( new Model() ); addTypeWithConstructor( new PathSampler() ); addTypeWithConstructor( new PosteriorPredictiveAnalysis() ); addTypeWithConstructor( new PosteriorPredictiveSimulation() ); addTypeWithConstructor( new PowerPosteriorAnalysis() ); addTypeWithConstructor( new SteppingStoneSampler() ); addTypeWithConstructor( new ValidationAnalysis() ); /* Add stopping rules (in folder "analysis/stoppingRules") (alphabetic order) */ addTypeWithConstructor( new GelmanRubinStoppingRule() ); addTypeWithConstructor( new GewekeStoppingRule() ); addTypeWithConstructor( new MaxIterationStoppingRule() ); addTypeWithConstructor( new MaxTimeStoppingRule() ); addTypeWithConstructor( new MinEssStoppingRule() ); addTypeWithConstructor( new StationarityStoppingRule() ); } catch(RbException& rbException) { RBOUT("Caught an exception while initializing types in the workspace\n"); std::ostringstream msg; rbException.print(msg); msg << std::endl; RBOUT(msg.str()); RBOUT("Please report this bug to the RevBayes Development Core Team"); RBOUT("Press any character to exit the program."); getchar(); exit(1); } }