00001
00002
00003
00004 #ifndef PARSER_H_
00005 #define PARSER_H_
00006
00013 #include <stdio.h>
00014 #include <map>
00015
00016 const char * nWord(const char *chKey,
00017 const char *chCard);
00018
00019 class Parser;
00020
00021 typedef void (*OptionParser)(Parser &);
00022
00023 struct CloudyCommand {
00024 const char *name;
00025 OptionParser action;
00026 };
00027
00028 bool isBoundaryChar(char c);
00029
00031 class Parser
00032 {
00033 char m_card[INPUT_LINE_LENGTH],
00034 m_card_raw[INPUT_LINE_LENGTH];
00035 long int m_len;
00036 const char * m_ptr;
00037 bool m_lgEOL;
00038 const CloudyCommand * const m_Commands;
00039 std::map<string,double> m_symtab;
00040 public:
00041 long int m_nqh, m_nInitFile;
00042 bool m_lgDSet, m_lgEOF;
00043
00044 explicit Parser(void) : m_Commands(NULL)
00045 {
00046 init();
00047 }
00048 explicit Parser(const CloudyCommand *commands) : m_Commands(commands)
00049 {
00050 init();
00051 }
00052 private:
00053 void init(void)
00054 {
00055 m_nqh = m_nInitFile = 0;
00056 m_lgDSet = m_lgEOF = false;
00057 setline("");
00058 }
00059 void newlineProcess(void)
00060 {
00061 strncpy(m_card,m_card_raw,INPUT_LINE_LENGTH);
00062 ::caps(m_card);
00063 m_len = INPUT_LINE_LENGTH;
00064 m_ptr = m_card;
00065 m_lgEOL = false;
00066 }
00067 public:
00068 bool getline(void);
00069 void setline(const char * const card)
00070 {
00071 ASSERT(INPUT_LINE_LENGTH > 0);
00072 ASSERT(strlen(card) < (unsigned) INPUT_LINE_LENGTH);
00073 strncpy(m_card_raw,card,INPUT_LINE_LENGTH);
00074 newlineProcess();
00075 }
00076
00077 void set_point(long int ipnt)
00078 {
00079 m_ptr = m_card+ipnt;
00080 }
00081 const char * nWord(const char *chKey) const;
00082 private:
00083 char chPoint( void ) const
00084 {
00085 return *m_ptr;
00086 }
00087 public:
00088 long int GetElem( void ) const;
00089 double FFmtRead( void );
00090 double getNumberPlain( const char *chDesc );
00091 double getNumberCheck( const char *chDesc );
00092 double getNumberDefault( const char *chDesc, double fdef );
00093 double getNumberCheckLogLinNegImplLog( const char *chDesc );
00094 double getNumberCheckAlwaysLog( const char *chDesc );
00095 double getNumberCheckAlwaysLogLim( const char *chDesc, double flim );
00096 double getNumberDefaultAlwaysLog( const char *chDesc, double fdef );
00097 double getNumberDefaultNegImplLog( const char *chDesc, double fdef );
00098 bool lgEOL(void) const
00099 {
00100 return m_lgEOL;
00101 }
00102 void setEOL(bool val)
00103 {
00104 m_lgEOL = val;
00105 }
00106 NORETURN void NoNumb(const char *chDesc) const;
00107 private:
00108 int nMatch1(const char *chKey) const
00109 {
00110 const char *p=chKey;
00111
00112 while (isspace(*p))
00113 ++p;
00114
00115 for (const char *q=p; *q; ++q)
00116 ASSERT(!islower(*q));
00117
00118 if ( !isBoundaryChar(*p))
00119 {
00120 const char *q = ::nWord(p, m_card);
00121 if (NULL == q)
00122 return 0;
00123 else
00124 return q-m_card+1;
00125 }
00126 else
00127 {
00128
00129
00130
00131 return ::nMatch(chKey, m_card);
00132 }
00133 }
00134 public:
00135 bool nMatch(const char *chKey) const
00136 {
00137 return nMatch1(chKey) != 0;
00138 }
00139 bool GetParam(const char *chKey, double *val)
00140 {
00141 int i = nMatch1(chKey);
00142 if (i > 0) {
00143 m_ptr = m_card+i-1;
00144 *val = FFmtRead();
00145 }
00146 return i>0;
00147 }
00148 bool GetRange(const char *chKey, double *val1, double *val2)
00149 {
00150 int i = nMatch1(chKey);
00151 if (i > 0) {
00152 m_ptr = m_card+i-1;
00153 *val1 = FFmtRead();
00154 *val2 = FFmtRead();
00155 }
00156 return i>0;
00157 }
00158 bool nMatchErase(const char *chKey)
00159 {
00160 const char *p=chKey;
00161 while (isspace(*p))
00162 ++p;
00163 int i = nMatch1(p);
00164 bool found = (i != 0);
00165 if(found)
00166 {
00167 char *ptr = m_card+i-1;
00168 const long len = strlen(p);
00169
00170 for (long i=0; i<len; ++i)
00171 {
00172 ptr[i] = ' ';
00173 }
00174 }
00175 return found;
00176 }
00177 int strcmp(const char *s2)
00178 {
00179 size_t len = strlen(s2);
00180 int val = ::strncmp(m_card, s2, len);
00181 if (val == 0)
00182 {
00183 m_ptr = m_card+len;
00184 }
00185 return val;
00186 }
00187 bool Command(const char *name, OptionParser doOpts)
00188 {
00189 bool lgFound = (this->strcmp(name) == 0);
00190 if ( lgFound )
00191 (*doOpts)(*this);
00192 return lgFound;
00193 }
00194 bool isComment(void) const;
00195 bool isCommandComment(void) const;
00196 bool isVar(void) const;
00197 std::string getVarName(void);
00198 void doSetVar(void);
00199 void echo(void) const;
00200 bool last(void) const
00201 {
00202 return m_lgEOF || m_card[0] == ' ';
00203 }
00204 int PrintLine(FILE *fp) const
00205 {
00206 return fprintf( fp, " ==%-.80s==\n", m_card_raw);
00207 }
00208 NORETURN void CommandError(void) const;
00209 int GetQuote( char *chLabel, bool lgABORT )
00210 {
00211 return ::GetQuote(chLabel, m_card, m_card_raw, lgABORT);
00212 }
00213 const char *StandardEnergyUnit(void) const;
00214 string StandardFluxUnit(void) const;
00215 string getCommand(long i)
00216 {
00217 m_ptr = m_card+i;
00218 return string(m_card).substr(0,i);
00219 }
00220 string getRawTail()
00221 {
00222 return string(m_card_raw+(m_ptr-m_card));
00223 }
00224 void help(FILE *fp) const;
00225 double getWave();
00226 double getWaveOpt();
00227 void getLineID(char *LabelBuf, realnum *wave);
00228 };
00229
00231 template <typename V>
00232 class KeyAction {
00233 const char * const m_keyword;
00234 V m_action;
00235 public:
00236 KeyAction(const char *keyword, const V &action) :
00237 m_keyword(keyword), m_action(action) {}
00238
00239 const char *key(void) const
00240 {
00241 return m_keyword;
00242 }
00243 void operator()(realnum *v) const
00244 {
00245 m_action(v);
00246 }
00247 };
00248
00250 template <typename V>
00251 inline KeyAction<V> MakeKeyAction(const char *keyword, const V &action)
00252 {
00253 return KeyAction<V>(keyword, action);
00254 }
00255
00257 class UnitConverter
00258 {
00259 const realnum m_unit;
00260 public:
00261 UnitConverter ( double unit ) : m_unit((realnum)unit) {}
00262
00263 void operator()( realnum *t ) const
00264 {
00265 *t *= m_unit;
00266 }
00267 };
00268
00271 template <typename T, typename V>
00272 bool parserProcess(Parser &p, T *list,
00273 unsigned long nlist, V *value)
00274 {
00275 bool lgFound = false;
00276 for (unsigned long option=0; option < nlist; ++option)
00277 {
00278 if( p.nWord( list[option].key() ) )
00279 {
00280 list[option]( value );
00281 lgFound = true;
00282 break;
00283 }
00284 }
00285 return lgFound;
00286 }
00287
00291 void ParseCosmicRays( Parser &p );
00292
00296 void ParseCosmology( Parser &p );
00297
00302 void ParseAbundancesNonSolar(Parser &p);
00303
00304 void ParseAbundances(Parser &p);
00305
00307 void ParseDont(Parser &p);
00308
00312 void ParseSave(Parser &p);
00313
00314 void parse_save_line(Parser &p,
00315
00316 bool lgLog3,
00317 char *chHeader);
00318
00319 void parse_save_average(
00320 Parser &p,
00321
00322 long int ipPun,
00323 char *chHeader);
00324
00325 void parse_save_colden(
00326 Parser &p,
00327
00328 char chHeader[] );
00329
00330 void Parse_Save_Line_RT(Parser &p);
00331
00333 void ParseAge(Parser &p);
00334
00338 void ParseAgn(Parser &p);
00339
00343 void ParseState(Parser &p);
00344
00350 void ParseBlackbody(Parser &p);
00351
00355 void ParseCompile(Parser &p );
00356
00358 void ParseConstant(Parser &p);
00359
00363 void ParseDLaw(Parser &p );
00364
00368 void ParseTLaw(Parser &p);
00369
00373 void ParseDrive(Parser &p );
00374
00379 void ParseGrain(Parser &p);
00380
00382 void ParseFluc(Parser &p);
00383
00385 void ParseHDEN(Parser &p);
00386
00391 void ParseAtomISO(long ipISO, Parser &p);
00392
00396 void ParseAtomH2(Parser &p );
00397
00401 void ParseGrid(Parser &p);
00402
00404 void ParseInit(Parser &p);
00405
00410 void ParseInterp(Parser &p);
00411
00417 void ParseIonParI(Parser &p);
00418
00425 void ParseIonParX(Parser &p);
00431 void ParseIonPar(Parser &p,
00432 char chType);
00433
00437 void ParseNorm(Parser &p);
00438
00442 void ParseOptimize(Parser &p);
00443
00447 void ParsePrint(Parser &p );
00448
00450 void ParseRadius(Parser &p);
00451
00453 void ParseSet(Parser &p);
00454
00460 void ParseTable(Parser &p);
00461
00463 void ParseTrace(Parser &p);
00464
00465
00466 void ParseExtinguish( Parser &p );
00467
00468
00469 void ParseIlluminate( Parser &p );
00470
00471
00472 void ParseCaseB(Parser &p );
00473
00475 void ParseTest(Parser &p);
00476
00478 void ParseAbsMag(Parser &p);
00479
00481 void ParseBackgrd(Parser &p);
00482
00484 void ParseCoronal(Parser &p);
00485
00487 void ParseElement(Parser &p);
00488
00494 void ParseCMB(double z,
00495 long int *nqh);
00496
00504 void ParseF_nu(
00505 Parser &p,
00506 const char *chType,
00507 bool lgNU2);
00508
00512 void ParseGlobule(Parser &p);
00513
00515 void ParseRangeOption(Parser &p);
00516
00518 void ParseMap(Parser &p);
00519
00521 void ParseMetal(Parser &p);
00522
00523 void ParsePrtLineSum(Parser &p);
00524
00526 void ParsePlot(Parser &p);
00527
00529 void ParsePowerlawContinuum(Parser &p);
00530
00532 void ParseRatio(Parser &p);
00533
00535 void ParseSphere(Parser &p);
00536
00538 void ParseStop(Parser &p);
00539
00543 void ParseCrashDo(Parser &p);
00544
00545
00546 #endif // _PARSER_H_