18 enum symType { symNull, symNumber, symOp, symVar };
21 explicit Token(
enum symType type) : s(
""), t(type) {}
22 explicit Token() : s(
""), t(symNull) {}
26typedef std::map<string,double>
symtab;
32 return ::nWord(chKey,
m_card);
37const char *
nWord(
const char *chKey,
44 while (isspace(*chKey))
49 const long lenkey = strlen(chKey);
52 bool atBoundary =
true, inQuote=
false;
53 for (
const char *ptr = chCard; *ptr; ++ptr)
63 if ( atBoundary && strncmp( ptr, chKey, lenkey) == 0 )
85 const bool lgAnyWhitespacePrecedesWord =
false;
87 if (lgAnyWhitespacePrecedesWord)
88 return isspace(c) ? true : false ;
90 return (! isalpha(c) ) && c !=
'_';
104 return ( *
m_ptr==
'$' );
108 std::string name(
"");
112 if (!(isalnum(c) || c ==
'_'))
134 fprintf(
ioQQQ,
"Expected '=' in variable definition\n");
157 fprintf(
ioQQQ,
" Unrecognized command. Key=\"%4.4s\". This is routine ParseCommands.\n",
159 fprintf(
ioQQQ,
" The line image was\n");
161 fprintf(
ioQQQ,
" Sorry.\n" );
176 return ::StandardEnergyUnit(
m_card);
180 return ::StandardFluxUnit(
m_card);
185 fprintf(fp,
"Available commands are:\n\n");
186 long int i=0, l=0, len;
203 fprintf(fp,
"\n\nSorry, no further help available yet -- try Hazy.\n\n");
220 for( i=0; i<(int)
LIMELM; ++i )
238 fprintf(
ioQQQ,
" There is a problem on the following command line:\n" );
240 fprintf(
ioQQQ,
" A value for %s should have been on this line.\n Sorry.\n",chDesc );
298 else if(!
nMatch(
"LINE") )
319 fprintf(
ioQQQ,
"WARNING - the log of %s is too "
320 "large, I shall probably crash. The value was %.2e\n",
363 while(
m_ptr < eol_ptr && ( chr = *
m_ptr++ ) !=
'\0' )
367 const char *lptr =
m_ptr;
369 if( lchr ==
'-' || lchr ==
'+' )
377 if(
m_ptr == eol_ptr || chr ==
'\0' )
384 deque<Token> chTokens(0);
385 bool lgCommaFound =
false, lgLastComma =
false;
388 lgCommaFound = lgLastComma;
391 if (chr ==
'^' || chr ==
'*' || chr ==
'/' )
393 chTokens.push_back(Token(Token::symOp));
394 chTokens.back().s += chr;
398 chTokens.push_back(Token(Token::symVar));
403 if (chTokens.size() == 0 || chTokens.back().t != Token::symNumber)
404 chTokens.push_back(Token(Token::symNumber));
405 chTokens.back().s += chr;
415 if(
m_ptr == eol_ptr )
419 while( isdigit(chr) || chr ==
'.' || chr ==
'-' || chr ==
'+' || chr ==
','
420 || chr ==
'e' || chr ==
'E' || chr ==
'^' || chr ==
'*' || chr ==
'/'
425 fprintf(
ioQQQ,
" PROBLEM - a comma was found embedded in a number, this is deprecated.\n" );
430 vector<double> valstack;
432 if (!lgParseOK || 1 != valstack.size())
434 fprintf(
ioQQQ,
" PROBLEM - syntax error in number\n");
438 double value = valstack[0];
449 strncpy( LabelBuf,
getCommand(4).c_str() , 4 );
470 if ( chTokens.size() < 1)
473 if (Token::symNumber == chTokens[0].t)
475 valstack.push_back(atof(chTokens[0].s.c_str()));
476 chTokens.pop_front();
479 if (Token::symVar == chTokens[0].t)
481 symtab::const_iterator var = tab.find(chTokens[0].s);
482 if (var == tab.end())
484 fprintf(
ioQQQ,
"ERROR: No value found for variable $%s\n",
485 chTokens[0].s.c_str());
488 valstack.push_back(var->second);
489 chTokens.pop_front();
498 const double v2 = valstack.back();
500 const double v1 = valstack.back();
517 fprintf(
ioQQQ,
"Unknown operator '%s'\n",op.c_str());
520 valstack.push_back(result);
528 vector<string> opstack;
534 if ( chTokens.size() == 0 )
537 if ( chTokens.size() < 2 )
540 if ( Token::symOp != chTokens[0].t ||
"^" != chTokens[0].s )
543 opstack.push_back(chTokens[0].s);
544 chTokens.pop_front();
550 while (!opstack.empty())
552 if (!
doop(valstack, opstack.back()))
563 if (!
ParseExp(chTokens, valstack, tab))
566 while ( chTokens.size() > 0 &&
567 Token::symOp == chTokens[0].t &&
568 (
"*" == chTokens[0].s ||
"/" == chTokens[0].s ) )
570 string op = chTokens[0].s;
571 chTokens.pop_front();
573 if (!
ParseExp(chTokens, valstack, tab))
576 if (!
doop(valstack, op))
#define DEBUG_ENTRY(funcname)
long int GetElem(void) const
bool nMatch(const char *chKey) const
const char * nWord(const char *chKey) const
const char * StandardEnergyUnit(void) const
double getNumberCheckAlwaysLog(const char *chDesc)
bool isCommandComment(void) const
char m_card[INPUT_LINE_LENGTH]
void getLineID(char *LabelBuf, realnum *wave)
bool isComment(void) const
string StandardFluxUnit(void) const
double getNumberPlain(const char *chDesc)
double getNumberCheckLogLinNegImplLog(const char *chDesc)
std::map< string, double > m_symtab
double getNumberCheck(const char *chDesc)
NORETURN void NoNumb(const char *chDesc) const
double getNumberCheckAlwaysLogLim(const char *chDesc, double flim)
std::string getVarName(void)
char m_card_raw[INPUT_LINE_LENGTH]
double getNumberDefault(const char *chDesc, double fdef)
string getCommand(long i)
double getNumberDefaultAlwaysLog(const char *chDesc, double fdef)
const CloudyCommand *const m_Commands
void newlineProcess(void)
NORETURN void CommandError(void) const
int PrintLine(FILE *fp) const
void help(FILE *fp) const
double getNumberDefaultNegImplLog(const char *chDesc, double fdef)
t_elementnames elementnames
bool isBoundaryChar(char c)
STATIC bool ParseExpr(deque< Token > &chTokens, vector< double > &valstack, const symtab &tab)
std::map< string, double > symtab
const char * nWord(const char *chKey, const char *chCard)
STATIC bool ParseExp(deque< Token > &chTokens, vector< double > &valstack, const symtab &tab)
STATIC bool ParseProduct(deque< Token > &chTokens, vector< double > &valstack, const symtab &tab)
STATIC bool doop(vector< double > &valstack, const string &op)
STATIC bool ParseNumber(deque< Token > &chTokens, vector< double > &valstack, const symtab &tab)