20 enum symType { symNull, symNumber, symOp, symVar };
23 explicit Token(
enum symType type) : s(
""), t(type) {}
24 explicit Token() : s(
""), t(symNull) {}
28 typedef std::map<string,double>
symtab;
62 const char *
nWord(
const char *chKey,
69 while (isspace(*chKey))
74 const long lenkey = strlen(chKey);
77 bool atBoundary =
true, inQuote=
false;
78 for (
const char *ptr = chCard; *ptr; ++ptr)
88 if ( atBoundary && strncmp( ptr, chKey, lenkey) == 0 )
120 for(
long i=0; i <
m_off; ++i )
132 const bool lgAnyWhitespacePrecedesWord =
false;
134 if (lgAnyWhitespacePrecedesWord)
135 return isspace(c) ?
true : false ;
137 return (! isalpha(c) ) && c !=
'_';
150 std::string name(
"");
154 if (!(isalnum(c) || c ==
'_'))
206 " A filename or label must be specified within double quotes, but no quotes were encountered on this command.\n"
207 " Name must be surrounded by exactly two double quotes, like \"name.txt\". \n"
220 size_t p0 = str_raw.find(
'\"' );
222 size_t p1 = ( p0 != string::npos ) ?
GetString( str_raw, p0, chLabel ) : string::npos;
225 if( p0 == string::npos || p1 == string::npos )
263 fprintf(
ioQQQ,
" Unrecognized command. Key=\"%4.4s\". This is routine ParseCommands.\n",
269 fprintf(
ioQQQ,
" This looks like an invalid old-style comment."
270 " Please use scripts/ccc.pl to convert this input script to convert to #.\n" );
297 fprintf(fp,
"Available commands are:\n\n");
298 long int i=0, l=0, len;
315 fprintf(fp,
"\n\nSorry, no further help available yet -- try Hazy.\n\n");
332 for( i=0; i<(int)
LIMELM; ++i )
350 fprintf(
ioQQQ,
" There is a problem on the following command line:\n" );
352 fprintf(
ioQQQ,
" A value for %s should have been on this line.\n Sorry.\n",chDesc );
417 else if(!
nMatch(
"LINE") )
439 "large, I shall probably crash. The value was %.2e\n",
484 if( lchr ==
'-' || lchr ==
'+' )
506 deque<Token> chTokens(0);
509 (isdigit(chr) || chr ==
'.' || chr ==
'-' || chr ==
'+'
510 || chr ==
'e' || chr ==
'E' || chr ==
'^' || chr ==
'*' || chr ==
'/'
514 if (chr ==
'^' || chr ==
'*' || chr ==
'/' )
516 chTokens.push_back(Token(Token::symOp));
517 chTokens.back().s += chr;
522 chTokens.push_back(Token(Token::symVar));
528 if (chTokens.size() == 0 || chTokens.back().t != Token::symNumber)
529 chTokens.push_back(Token(Token::symNumber));
530 chTokens.back().s += chr;
535 ASSERT (chTokens.size() != 0);
538 vector<double> valstack;
540 if (!lgParseOK || 1 != valstack.size())
542 fprintf(
ioQQQ,
" PROBLEM - syntax error in number or expression on line\n");
548 double value = valstack[0];
561 " input line too short to provide %ld character label\n"
562 "== %-80s ==\n", nchar,
m_card);
566 return string(
m_card).substr(0,nchar);
579 fprintf(
ioQQQ,
"getLineID found invalid quoted string:\n" );
622 if ( chTokens.size() < 1)
625 if (Token::symNumber == chTokens[0].t)
627 valstack.push_back(atof(chTokens[0].s.c_str()));
628 chTokens.pop_front();
631 if (Token::symVar == chTokens[0].t)
633 symtab::const_iterator var = tab.find(chTokens[0].s);
634 if (var == tab.end())
636 fprintf(
ioQQQ,
"ERROR: No value found for variable $%s\n",
637 chTokens[0].s.c_str());
640 valstack.push_back(var->second);
641 chTokens.pop_front();
651 const double v2 = valstack.back();
653 const double v1 = valstack.back();
673 valstack.push_back(result);
682 vector<string> opstack;
688 if ( chTokens.size() == 0 )
691 if ( chTokens.size() < 2 )
694 if ( Token::symOp != chTokens[0].t ||
"^" != chTokens[0].s )
697 opstack.push_back(chTokens[0].s);
698 chTokens.pop_front();
704 while (!opstack.empty())
706 if (!
doop(valstack, opstack.back()))
718 if (!
ParseExp(chTokens, valstack, tab))
721 while ( chTokens.size() > 0 &&
722 Token::symOp == chTokens[0].t &&
723 (
"*" == chTokens[0].s ||
"/" == chTokens[0].s ) )
725 string op = chTokens[0].s;
726 chTokens.pop_front();
728 if (!
ParseExp(chTokens, valstack, tab))
731 if (!
doop(valstack, op))
749 size_t len = strlen(s2);
750 if (::strncmp(
m_card, s2, len) != 0)
753 while (isspace(
m_card[len-1]))
779 fprintf(
ioQQQ,
" Hit EOF while reading element list; use END to end list.\n" );
794 fprintf(
ioQQQ,
" There must be a two numbers on this line, or END.\n" );
801 fprintf(
ioQQQ,
" There must be a two numbers on this line, or END.\n" );
819 " at end of input term, error after '%s'\n",s.
value.c_str());
831 if (c !=
' ' && c !=
'\t')
920 " at end of input term\n");
945 fprintf(
ioQQQ,
"Parser error, character not recognized '%c'\n",
959 " Save %s hit EOF while reading list; use END to end list.\n" ,chName);
961 " This command requires either a species within quotes or the keyword ALL.\n" );
970 list.push_back(chTerm);
987 if (table.
nvals != 0)
989 fprintf(
ioQQQ,
" Warning: over-writing existing table\n" );
998 fprintf(
ioQQQ,
" No pairs entered - can\'t interpolate.\n Sorry.\n" );
1022 NoNumb(
"radius, value pair on each line");
1023 table.
dist.push_back( dist );
1024 table.
val.push_back( val );
1030 for(
long i=1; i < table.
nvals; i++ )
1033 if( table.
dist[i] <= table.
dist[i-1] )
1035 fprintf(
ioQQQ,
" Radii must be in increasing order. Sorry.\n" );
bool nMatch(const char *chKey) const
bool hasCommand(const char *s2)
Symbol maybeNumber(bool numOK, const Symbol &s)
double getNumberCheckLogLinNegImplLog(const char *chDesc)
STATIC bool ParseProduct(deque< Token > &chTokens, vector< double > &valstack, const symtab &tab)
void readList(vector< string > &list, const char *chName)
int GetQuote(string &chLabel)
char m_card[INPUT_LINE_LENGTH]
double getNumberDefaultAlwaysLog(const char *chDesc, double fdef)
STATIC bool ParseExpr(deque< Token > &chTokens, vector< double > &valstack, const symtab &tab)
bool isBoundaryChar(char c)
STATIC bool doop(vector< double > &valstack, const string &op)
void trimTrailingWhiteSpace(string &str)
NORETURN void StringError() const
double getNumberPlain(const char *chDesc)
char m_card_raw[INPUT_LINE_LENGTH]
t_elementnames elementnames
string StandardFluxUnit(void) const
void showLocation(FILE *io=ioQQQ) const
const char * StandardEnergyUnit(void) const
char m_card_comment[INPUT_LINE_LENGTH]
const int INPUT_LINE_LENGTH
NORETURN void NoNumb(const char *chDesc) const
STATIC bool ParseExp(deque< Token > &chTokens, vector< double > &valstack, const symtab &tab)
long int GetElem(void) const
const char * nWord(const char *chKey) const
string getFirstChunk(long i)
string StandardFluxUnit(const char *chCard)
char chElementNameShort[LIMELM][CHARS_ELEMENT_NAME_SHORT]
const char * nWord(const char *chKey, const char *chCard)
STATIC double dist(long, realnum[], realnum[])
double getNumberCheckAlwaysLogLim(const char *chDesc, double flim)
void help(FILE *fp) const
const char * StandardEnergyUnit(const char *chCard)
NORETURN void Error(const char *msg) const
#define DEBUG_ENTRY(funcname)
STATIC bool ParseNumber(deque< Token > &chTokens, vector< double > &valstack, const symtab &tab)
double getNumberCheckAlwaysLog(const char *chDesc)
const CloudyCommand *const m_Commands
double getNumberDefault(const char *chDesc, double fdef)
std::map< string, double > symtab
int fprintf(const Output &stream, const char *format,...)
NORETURN void CommandError(void) const
void getPairs(vector< double > &a, vector< double > &b)
int PrintLine(FILE *fp) const
std::string getVarName(void)
void readLaw(DepthTable &table)
double getNumberDefaultNegImplLog(const char *chDesc, double fdef)
std::map< string, double > m_symtab
bool isComment(void) const
double getNumberCheck(const char *chDesc)