00001
00002
00003
00004 #ifndef PARSER_H_
00005 #define PARSER_H_
00006
00013 #include <stdio.h>
00014
00015 const char * nWord(const char *chKey,
00016 const char *chCard);
00017
00018 class Parser;
00019
00020 typedef void (*OptionParser)(Parser &);
00021
00022 struct CloudyCommand {
00023 const char *name;
00024 OptionParser action;
00025 };
00026
00027 bool isBoundaryChar(char c);
00028
00030 class Parser
00031 {
00032 char m_card[INPUT_LINE_LENGTH],
00033 m_card_raw[INPUT_LINE_LENGTH];
00034 long int m_len;
00035 const char * m_ptr;
00036 bool m_lgEOL;
00037 const CloudyCommand * const m_Commands;
00038 public:
00039 long int m_nqh, m_nInitFile;
00040 bool m_lgDSet, m_lgEOF;
00041
00042 explicit Parser(void) : m_Commands(NULL)
00043 {
00044 setline("");
00045 }
00046 explicit Parser(const CloudyCommand *commands) : m_Commands(commands)
00047 {
00048 setline("");
00049 }
00050 private:
00051 void newlineProcess(void)
00052 {
00053 strncpy(m_card,m_card_raw,INPUT_LINE_LENGTH);
00054 ::caps(m_card);
00055 m_len = INPUT_LINE_LENGTH;
00056 m_ptr = m_card;
00057 m_lgEOL = false;
00058 }
00059 public:
00060 bool getline(void);
00061 void setline(const char * const card)
00062 {
00063 ASSERT(INPUT_LINE_LENGTH > 0);
00064 ASSERT(strlen(card) < (unsigned) INPUT_LINE_LENGTH);
00065 strncpy(m_card_raw,card,INPUT_LINE_LENGTH);
00066 newlineProcess();
00067 }
00068
00069 void set_point(long int ipnt)
00070 {
00071 m_ptr = m_card+ipnt;
00072 }
00073 const char * nWord(const char *chKey) const;
00074 private:
00075 char chPoint( void ) const
00076 {
00077 return *m_ptr;
00078 }
00079 public:
00080 long int GetElem( void ) const;
00081 double FFmtRead( void );
00082 double getNumberPlain( const char *chDesc );
00083 double getNumberCheck( const char *chDesc );
00084 double getNumberDefault( const char *chDesc, double fdef );
00085 double getNumberCheckLogLinNegImplLog( const char *chDesc );
00086 double getNumberCheckAlwaysLog( const char *chDesc );
00087 double getNumberCheckAlwaysLogLim( const char *chDesc, double flim );
00088 double getNumberDefaultAlwaysLog( const char *chDesc, double fdef );
00089 double getNumberDefaultNegImplLog( const char *chDesc, double fdef );
00090 bool lgEOL(void) const
00091 {
00092 return m_lgEOL;
00093 }
00094 void setEOL(bool val)
00095 {
00096 m_lgEOL = val;
00097 }
00098 NORETURN void NoNumb(const char *chDesc) const;
00099 private:
00100 int nMatch1(const char *chKey) const
00101 {
00102 const char *p=chKey;
00103
00104 while (isspace(*p))
00105 ++p;
00106
00107 for (const char *q=p; *q; ++q)
00108 ASSERT(!islower(*q));
00109
00110 if ( !isBoundaryChar(*p))
00111 {
00112 const char *q = ::nWord(p, m_card);
00113 if (NULL == q)
00114 return 0;
00115 else
00116 return q-m_card+1;
00117 }
00118 else
00119 {
00120
00121
00122
00123 return ::nMatch(chKey, m_card);
00124 }
00125 }
00126 public:
00127 bool nMatch(const char *chKey) const
00128 {
00129 return nMatch1(chKey) != 0;
00130 }
00131 bool GetParam(const char *chKey, double *val)
00132 {
00133 int i = nMatch1(chKey);
00134 if (i > 0) {
00135 m_ptr = m_card+i-1;
00136 *val = FFmtRead();
00137 }
00138 return i>0;
00139 }
00140 bool GetRange(const char *chKey, double *val1, double *val2)
00141 {
00142 int i = nMatch1(chKey);
00143 if (i > 0) {
00144 m_ptr = m_card+i-1;
00145 *val1 = FFmtRead();
00146 *val2 = FFmtRead();
00147 }
00148 return i>0;
00149 }
00150 bool nMatchErase(const char *chKey)
00151 {
00152 const char *p=chKey;
00153 while (isspace(*p))
00154 ++p;
00155 int i = nMatch1(p);
00156 bool found = (i != 0);
00157 if(found)
00158 {
00159 char *ptr = m_card+i-1;
00160 const long len = strlen(p);
00161
00162 for (long i=0; i<len; ++i)
00163 {
00164 ptr[i] = ' ';
00165 }
00166 }
00167 return found;
00168 }
00169 int strcmp(const char *s2)
00170 {
00171 size_t len = strlen(s2);
00172 int val = ::strncmp(m_card, s2, len);
00173 if (val == 0)
00174 {
00175 m_ptr = m_card+len;
00176 }
00177 return val;
00178 }
00179 bool Command(const char *name, OptionParser doOpts)
00180 {
00181 bool lgFound = (this->strcmp(name) == 0);
00182 if ( lgFound )
00183 (*doOpts)(*this);
00184 return lgFound;
00185 }
00186 bool isComment(void) const;
00187 bool isCommandComment(void) const;
00188 void echo(void) const;
00189 bool last(void) const
00190 {
00191 return m_lgEOF || m_card[0] == ' ';
00192 }
00193 int PrintLine(FILE *fp) const
00194 {
00195 return fprintf( fp, " ==%-.80s==\n", m_card_raw);
00196 }
00197 NORETURN void CommandError(void) const;
00198 int GetQuote( char *chLabel, bool lgABORT )
00199 {
00200 return ::GetQuote(chLabel, m_card, m_card_raw, lgABORT);
00201 }
00202 const char *StandardEnergyUnit(void) const;
00203 string StandardFluxUnit(void) const;
00204 string getCommand(long i)
00205 {
00206 m_ptr = m_card+i;
00207 return string(m_card).substr(0,i);
00208 }
00209 string getCommandRaw(long i)
00210 {
00211 m_ptr = m_card+i;
00212 return string(m_card_raw).substr(0,i);
00213 }
00214 string getRawTail()
00215 {
00216 return string(m_card_raw+(m_ptr-m_card));
00217 }
00218 void help(FILE *fp) const;
00219 double getWave();
00220 double getWaveOpt();
00221 };
00222
00224 template <typename V>
00225 class KeyAction {
00226 const char * const m_keyword;
00227 V m_action;
00228 public:
00229 KeyAction(const char *keyword, const V &action) :
00230 m_keyword(keyword), m_action(action) {}
00231
00232 const char *key(void) const
00233 {
00234 return m_keyword;
00235 }
00236 void operator()(realnum *v) const
00237 {
00238 m_action(v);
00239 }
00240 };
00241
00243 template <typename V>
00244 inline KeyAction<V> MakeKeyAction(const char *keyword, const V &action)
00245 {
00246 return KeyAction<V>(keyword, action);
00247 }
00248
00250 class UnitConverter
00251 {
00252 const realnum m_unit;
00253 public:
00254 UnitConverter ( double unit ) : m_unit((realnum)unit) {}
00255
00256 void operator()( realnum *t ) const
00257 {
00258 *t *= m_unit;
00259 }
00260 };
00261
00264 template <typename T, typename V>
00265 bool parserProcess(Parser &p, T *list,
00266 unsigned long nlist, V *value)
00267 {
00268 bool lgFound = false;
00269 for (unsigned long option=0; option < nlist; ++option)
00270 {
00271 if( p.nWord( list[option].key() ) )
00272 {
00273 list[option]( value );
00274 lgFound = true;
00275 break;
00276 }
00277 }
00278 return lgFound;
00279 }
00280
00284 void ParseCosmicRays( Parser &p );
00285
00289 void ParseCosmology( Parser &p );
00290
00295 void ParseAbundancesNonSolar(Parser &p);
00296
00297 void ParseAbundances(Parser &p);
00298
00300 void ParseDont(Parser &p);
00301
00305 void ParseSave(Parser &p);
00306
00307 void parse_save_line(Parser &p,
00308
00309 bool lgLog3,
00310 char *chHeader);
00311
00312 void parse_save_average(
00313 Parser &p,
00314
00315 long int ipPun,
00316 char *chHeader);
00317
00318 void parse_save_colden(
00319 Parser &p,
00320
00321 char chHeader[] );
00322
00323 void Parse_Save_Line_RT(Parser &p);
00324
00326 void ParseAge(Parser &p);
00327
00331 void ParseAgn(Parser &p);
00332
00336 void ParseState(Parser &p);
00337
00343 void ParseBlackbody(Parser &p);
00344
00348 void ParseCompile(Parser &p );
00349
00351 void ParseConstant(Parser &p);
00352
00356 void ParseDLaw(Parser &p );
00357
00361 void ParseTLaw(Parser &p);
00362
00366 void ParseDrive(Parser &p );
00367
00372 void ParseGrain(Parser &p);
00373
00375 void ParseFluc(Parser &p);
00376
00378 void ParseHDEN(Parser &p);
00379
00384 void ParseAtomISO(long ipISO, Parser &p);
00385
00389 void ParseAtomH2(Parser &p );
00390
00394 void ParseGrid(Parser &p);
00395
00397 void ParseInit(Parser &p);
00398
00403 void ParseInterp(Parser &p);
00404
00410 void ParseIonParI(Parser &p);
00411
00418 void ParseIonParX(Parser &p);
00424 void ParseIonPar(Parser &p,
00425 char chType);
00426
00430 void ParseNorm(Parser &p);
00431
00435 void ParseOptimize(Parser &p);
00436
00440 void ParsePrint(Parser &p );
00441
00443 void ParseRadius(Parser &p);
00444
00446 void ParseSet(Parser &p);
00447
00453 void ParseTable(Parser &p);
00454
00456 void ParseTrace(Parser &p);
00457
00458
00459 void ParseExtinguish( Parser &p );
00460
00461
00462 void ParseIlluminate( Parser &p );
00463
00464
00465 void ParseCaseB(Parser &p );
00466
00468 void ParseTest(Parser &p);
00469
00471 void ParseAbsMag(Parser &p);
00472
00474 void ParseBackgrd(Parser &p);
00475
00477 void ParseCoronal(Parser &p);
00478
00480 void ParseElement(Parser &p);
00481
00487 void ParseCMB(double z,
00488 long int *nqh);
00489
00497 void ParseF_nu(
00498 Parser &p,
00499 const char *chType,
00500 bool lgNU2);
00501
00505 void ParseGlobule(Parser &p);
00506
00508 void ParseRangeOption(Parser &p);
00509
00511 void ParseMap(Parser &p);
00512
00514 void ParseMetal(Parser &p);
00515
00516 void ParsePrtLineSum(Parser &p);
00517
00519 void ParsePlot(Parser &p);
00520
00522 void ParsePowerlawContinuum(Parser &p);
00523
00525 void ParseRatio(Parser &p);
00526
00528 void ParseSphere(Parser &p);
00529
00531 void ParseStop(Parser &p);
00532
00536 void ParseCrashDo(Parser &p);
00537
00538
00539 #endif // _PARSER_H_