// baselexer.cc see license.txt for copyright and terms of use // code for baselexer.h #include "baselexer.h" // this module #include "strtable.h" // StringTable #include "exc.h" // throw_XOpen #include // ifstream #if defined(__GNUC__) && (__GNUC__ > 2) // gcc-3 doesn't have istrstream (but it is standard!), so fake it #include // istringstream #undef string // in case the string->mystring definition is active inline istream *construct_istrstream(char const *buf, int len) { return new std::istringstream(std::string(buf, len)); } #else // should work on any compiler that implements the C++98 standard // (istrstream is deprecated but still standard) #include // istrstream inline istream *construct_istrstream(char const *buf, int len) { return new istrstream(buf, len); } #endif // this function effectively lets me initialize one of the // members before initing a base class istream *BaseLexer::openFile(char const *fname) { // 2005-01-17: open in binary mode to coincide with srcloc.cc // doing the same, for cygwin reasons this->inputStream = new ifstream(fname, ios::in | ios::binary); if (!*inputStream) { throw_XOpen(fname); } return inputStream; } BaseLexer::BaseLexer(StringTable &s, char const *fname) : yyFlexLexer(openFile(fname)), // 'inputStream' is initialized by 'openFile' srcFile(NULL), // changed below nextLoc(SL_UNKNOWN), // changed below curLine(1), strtable(s), errors(0), warnings(0) { srcFile = sourceLocManager->getInternalFile(fname); loc = sourceLocManager->encodeBegin(fname); nextLoc = loc; } istream *BaseLexer::openString(char const *buf, int len) { this->inputStream = construct_istrstream(buf, len); return inputStream; } BaseLexer::BaseLexer(StringTable &s, SourceLoc initLoc, char const *buf, int len) : yyFlexLexer(openString(buf, len)), // 'inputStream' is initialized by 'openString' srcFile(NULL), // changed below nextLoc(initLoc), curLine(0), // changed below strtable(s), errors(0), warnings(0) { // decode the given location char const *fname; int line, col; sourceLocManager->decodeLineCol(initLoc, fname, line, col); // finish initializing data members srcFile = sourceLocManager->getInternalFile(fname); curLine = line; loc = initLoc; } BaseLexer::~BaseLexer() { delete inputStream; } StringRef BaseLexer::addString(char *str, int len) { // (copied from gramlex.cc, GrammarBaseLexer::addString) // write a null terminator temporarily char wasThere = str[len]; if (wasThere) { str[len] = 0; StringRef ret = strtable.add(str); str[len] = wasThere; return ret; } else { return strtable.add(str); } } void BaseLexer::whitespace() { updLoc(); // scan for newlines char *p = yytext, *endp = yytext+yyleng; for (; p < endp; p++) { if (*p == '\n') { curLine++; } } } int BaseLexer::tok(int t) { updLoc(); sval = NULL_SVAL; // catch mistaken uses of 'sval' for single-spelling tokens return t; } void BaseLexer::err(char const *msg) { errors++; cerr << toString(loc) << ": error: " << msg << endl; } void BaseLexer::warning(char const *msg) { warnings++; cerr << toString(loc) << ": warning: " << msg << endl; } STATICDEF void BaseLexer::tokenFunc(LexerInterface *lex) { BaseLexer *ths = static_cast(lex); // call into the flex lexer; this updates 'loc' and sets // 'sval' as appropriate ths->type = ths->yylex(); } BaseLexer::NextTokenFunc BaseLexer::getTokenFunc() const { return &BaseLexer::tokenFunc; } // EOF