16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-22 00:09:18 +02:00

Revert "Some parser optimisations"

This reverts commit caff196b06.
This commit is contained in:
2026-01-05 00:13:59 +01:00
parent caff196b06
commit 24c2cf2771
2 changed files with 314 additions and 417 deletions

View File

@@ -24,321 +24,259 @@ http://mozilla.org/MPL/2.0/.
// cParser -- generic class for parsing text data. // cParser -- generic class for parsing text data.
// constructors // constructors
cParser::cParser(std::string const &Stream, buffertype const Type, std::string Path, bool const Loadtraction, std::vector<std::string> Parameters, bool allowRandom) cParser::cParser( std::string const &Stream, buffertype const Type, std::string Path, bool const Loadtraction, std::vector<std::string> Parameters, bool allowRandom ) :
: mPath(Path), LoadTraction(Loadtraction), allowRandomIncludes(allowRandom) mPath(Path),
{ LoadTraction( Loadtraction ),
// store to calculate sub-sequent includes from relative path allowRandomIncludes(allowRandom) {
if (Type == buffertype::buffer_FILE) // store to calculate sub-sequent includes from relative path
{ if( Type == buffertype::buffer_FILE ) {
mFile = Stream; mFile = Stream;
} }
// reset pointers and attach proper type of buffer // reset pointers and attach proper type of buffer
switch (Type) switch (Type) {
{ case buffer_FILE: {
case buffer_FILE: Path.append( Stream );
{ mStream = std::make_shared<std::ifstream>( Path, std::ios_base::binary );
Path.append(Stream); // content of *.inc files is potentially grouped together
mStream = std::make_shared<std::ifstream>(Path, std::ios_base::binary); if( ( Stream.size() >= 4 )
// content of *.inc files is potentially grouped together && ( ToLower( Stream.substr( Stream.size() - 4 ) ) == ".inc" ) ) {
if ((Stream.size() >= 4) && (ToLower(Stream.substr(Stream.size() - 4)) == ".inc")) mIncFile = true;
{ scene::Groups.create();
mIncFile = true; }
scene::Groups.create(); break;
} }
break; case buffer_TEXT: {
} mStream = std::make_shared<std::istringstream>( Stream );
case buffer_TEXT: break;
{ }
mStream = std::make_shared<std::istringstream>(Stream); default: {
break; break;
} }
default: }
{ // calculate stream size
break; if (mStream)
} {
} if( true == mStream->fail() ) {
// calculate stream size ErrorLog( "Failed to open file \"" + Path + "\"" );
if (mStream) }
{ else {
if (true == mStream->fail()) mSize = mStream->rdbuf()->pubseekoff( 0, std::ios_base::end );
{ mStream->rdbuf()->pubseekoff( 0, std::ios_base::beg );
ErrorLog("Failed to open file \"" + Path + "\""); mLine = 1;
} }
else }
{ // set parameter set if one was provided
mSize = mStream->rdbuf()->pubseekoff(0, std::ios_base::end); if( false == Parameters.empty() ) {
mStream->rdbuf()->pubseekoff(0, std::ios_base::beg); parameters.swap( Parameters );
mLine = 1; }
}
}
// set parameter set if one was provided
if (false == Parameters.empty())
{
parameters.swap(Parameters);
}
} }
// destructor // destructor
cParser::~cParser() cParser::~cParser() {
{
if (true == mIncFile) if( true == mIncFile ) {
{ // wrap up the node group holding content of processed file
// wrap up the node group holding content of processed file scene::Groups.close();
scene::Groups.close(); }
}
} }
template <> glm::vec3 cParser::getToken(bool const ToLower, char const *Break) template <>
{ glm::vec3
// NOTE: this specialization ignores default arguments cParser::getToken( bool const ToLower, char const *Break ) {
getTokens(3, false, "\n\r\t ,;[]"); // NOTE: this specialization ignores default arguments
glm::vec3 output; getTokens( 3, false, "\n\r\t ,;[]" );
*this >> output.x >> output.y >> output.z; glm::vec3 output;
return output; *this
>> output.x
>> output.y
>> output.z;
return output;
}; };
template <> cParser &cParser::operator>>(std::string &Right) template<>
{ cParser&
cParser::operator>>( std::string &Right ) {
if (true == this->tokens.empty()) if( true == this->tokens.empty() ) { return *this; }
{
return *this;
}
Right = this->tokens.front(); Right = this->tokens.front();
this->tokens.pop_front(); this->tokens.pop_front();
return *this; return *this;
} }
template <> cParser &cParser::operator>>(bool &Right) template<>
{ cParser&
cParser::operator>>( bool &Right ) {
if (true == this->tokens.empty()) if( true == this->tokens.empty() ) { return *this; }
{
return *this;
}
Right = ((this->tokens.front() == "true") || (this->tokens.front() == "yes") || (this->tokens.front() == "1")); Right = ( ( this->tokens.front() == "true" )
this->tokens.pop_front(); || ( this->tokens.front() == "yes" )
|| ( this->tokens.front() == "1" ) );
this->tokens.pop_front();
return *this; return *this;
} }
template <> bool cParser::getToken<bool>(bool const ToLower, const char *Break) template <>
{ bool
cParser::getToken<bool>( bool const ToLower, const char *Break ) {
auto const token = getToken<std::string>(true, Break); auto const token = getToken<std::string>( true, Break );
return ((token == "true") || (token == "yes") || (token == "1")); return ( ( token == "true" )
|| ( token == "yes" )
|| ( token == "1" ) );
} }
// methods // methods
cParser &cParser::autoclear(bool const Autoclear) cParser &
{ cParser::autoclear( bool const Autoclear ) {
m_autoclear = Autoclear; m_autoclear = Autoclear;
if (mIncludeParser) if( mIncludeParser ) { mIncludeParser->autoclear( Autoclear ); }
{
mIncludeParser->autoclear(Autoclear);
}
return *this; return *this;
} }
bool cParser::getTokens(unsigned int Count, bool ToLower, const char *Break) bool cParser::getTokens(unsigned int Count, bool ToLower, const char *Break)
{ {
if (true == m_autoclear) if( true == m_autoclear ) {
{ // legacy parser behaviour
// legacy parser behaviour tokens.clear();
tokens.clear(); }
} /*
/* if (LoadTraction==true)
if (LoadTraction==true) trtest="niemaproblema"; //wczytywać
trtest="niemaproblema"; //wczytywać else
else trtest="x"; //nie wczytywać
trtest="x"; //nie wczytywać */
*/ /*
/* int i;
int i; this->str("");
this->str(""); this->clear();
this->clear(); */
*/ for (unsigned int i = tokens.size(); i < Count; ++i)
for (unsigned int i = tokens.size(); i < Count; ++i) {
{ std::string token = readToken(ToLower, Break);
std::string token = readToken(ToLower, Break); if( true == token.empty() ) {
if (true == token.empty()) // no more tokens
{ break;
// no more tokens }
break; // collect parameters
} tokens.emplace_back( token );
// collect parameters /*
tokens.emplace_back(token); if (i == 0)
/* this->str(token);
if (i == 0) else
this->str(token); {
else std::string temp = this->str();
{ temp.append("\n");
std::string temp = this->str(); temp.append(token);
temp.append("\n"); this->str(temp);
temp.append(token); }
this->str(temp); */
} }
*/ if (tokens.size() < Count)
} return false;
if (tokens.size() < Count) else
return false; return true;
else
return true;
} }
std::string cParser::readToken(bool ToLower, const char *Break) std::string cParser::readToken( bool ToLower, const char *Break ) {
{
std::string token; std::string token;
token.reserve(128); if( mIncludeParser ) {
// see if there's include parsing going on. clean up when it's done.
token = mIncludeParser->readToken( ToLower, Break );
if( true == token.empty() ) {
mIncludeParser = nullptr;
}
}
if( true == token.empty() ) {
// get the token yourself if the delegation attempt failed
char c { 0 };
do {
while( mStream->peek() != EOF && strchr( Break, c = mStream->get() ) == NULL ) {
if( ToLower )
c = tolower( c );
token += c;
if( findQuotes( token ) ) // do glue together words enclosed in quotes
continue;
if( skipComments && trimComments( token ) ) // don't glue together words separated with comment
break;
}
if( c == '\n' ) {
// update line counter
++mLine;
}
} while( token == "" && mStream->peek() != EOF ); // double check in case of consecutive separators
}
// check the first token for potential presence of utf bom
if( mFirstToken ) {
mFirstToken = false;
if( token.rfind( "\xef\xbb\xbf", 0 ) == 0 ) {
token.erase( 0, 3 );
}
if( true == token.empty() ) {
// potentially possible if our first token was standalone utf bom
token = readToken( ToLower, Break );
}
}
auto &breakTable = breakTables[Break]; if( false == parameters.empty() ) {
if (breakTable[0] == false) // if there's parameter list, check the token for potential parameters to replace
{ // inicjalizacja tylko raz size_t pos; // początek podmienianego ciągu
for (char c : std::string(Break)) while( ( pos = token.find( "(p" ) ) != std::string::npos ) {
breakTable[(unsigned char)c] = true; // check if the token is a parameter which should be replaced with stored true value
} auto const parameter{ token.substr( pos + 2, token.find( ")", pos ) - ( pos + 2 ) ) }; // numer parametru
token.erase( pos, token.find( ")", pos ) - pos + 1 ); // najpierw usunięcie "(pN)"
size_t nr = atoi( parameter.c_str() ) - 1;
if( nr < parameters.size() ) {
token.insert( pos, parameters.at( nr ) ); // wklejenie wartości parametru
if( ToLower )
for( ; pos < parameters.at( nr ).size(); ++pos )
token[ pos ] = tolower( token[ pos ] );
}
else
token.insert( pos, "none" ); // zabezpieczenie przed brakiem parametru
}
}
if (mIncludeParser) // launch child parser if include directive found.
{ // NOTE: parameter collecting uses default set of token separators.
// see if there's include parsing going on. clean up when it's done. if( expandIncludes && token == "include" ) {
token = mIncludeParser->readToken(ToLower, Break);
if (true == token.empty())
{
mIncludeParser = nullptr;
}
}
if (true == token.empty())
{
// get the token yourself if the delegation attempt failed
char c{0};
do
{
while (mStream->peek() != EOF)
{
c = mStream->peek();
if (breakTable[(unsigned char)c])
break;
mStream->get(); // dopiero TERAZ konsumujemy
if (ToLower)
c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
token += c;
if (c == '"' && findQuotes(token))
continue;
if (skipComments && trimComments(token))
break;
}
c = mStream->get();
if (c == '\n')
{
++mLine;
// PRZERWIJ, ale NIE ZJADAJ \n jako separatora tokenów
break;
}
} while (token == "" && mStream->peek() != EOF); // double check in case of consecutive separators
}
// check the first token for potential presence of utf bom
if (mFirstToken)
{
mFirstToken = false;
if (token.rfind("\xef\xbb\xbf", 0) == 0)
{
token.erase(0, 3);
}
if (true == token.empty())
{
// potentially possible if our first token was standalone utf bom
token = readToken(ToLower, Break);
}
}
if (!parameters.empty())
{
size_t pos = 0;
while ((pos = token.find("(p", pos)) != std::string::npos)
{
size_t end = token.find(')', pos + 2);
if (end == std::string::npos)
break; // uszkodzony zapis, przerywamy
// parsowanie numeru parametru
int idx = 0;
bool ok = true;
for (size_t i = pos + 2; i < end; ++i)
{
if (token[i] < '0' || token[i] > '9')
{
ok = false;
break;
}
idx = idx * 10 + (token[i] - '0');
}
std::string replacement;
if (ok && idx > 0 && static_cast<size_t>(idx - 1) < parameters.size())
replacement = parameters[idx - 1];
else
replacement = "none";
if (ToLower)
{
for (char &c : replacement)
c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
}
token.replace(pos, end - pos + 1, replacement);
pos += replacement.size(); // przesuwamy się dalej
}
}
// launch child parser if include directive found.
// NOTE: parameter collecting uses default set of token separators.
if (expandIncludes && token == "include")
{
std::string includefile = allowRandomIncludes ? deserialize_random_set(*this) : readToken(ToLower); // nazwa pliku std::string includefile = allowRandomIncludes ? deserialize_random_set(*this) : readToken(ToLower); // nazwa pliku
replace_slashes(includefile); replace_slashes(includefile);
if ((true == LoadTraction) || ((false == contains(includefile, "tr/")) && (false == contains(includefile, "tra/")))) if ((true == LoadTraction) ||
((false == contains(includefile, "tr/")) && (false == contains(includefile, "tra/"))))
{ {
if (false == contains(includefile, "_ter.scm")) if (false == contains(includefile, "_ter.scm"))
{ {
if (Global.ParserLogIncludes) if (Global.ParserLogIncludes) {
{
// WriteLog("including: " + includefile); // WriteLog("including: " + includefile);
} }
mIncludeParser = std::make_unique<cParser>(includefile, buffer_FILE, mPath, LoadTraction, readParameters(*this)); mIncludeParser = std::make_shared<cParser>(includefile, buffer_FILE, mPath, LoadTraction, readParameters(*this));
mIncludeParser->allowRandomIncludes = allowRandomIncludes; mIncludeParser->allowRandomIncludes = allowRandomIncludes;
mIncludeParser->autoclear(m_autoclear); mIncludeParser->autoclear(m_autoclear);
if (mIncludeParser->mSize <= 0) if (mIncludeParser->mSize <= 0) {
{
ErrorLog("Bad include: can't open file \"" + includefile + "\""); ErrorLog("Bad include: can't open file \"" + includefile + "\"");
} }
} }
else else
{ {
if (true == Global.file_binary_terrain_state) if(true == Global.file_binary_terrain_state)
{ {
WriteLog("SBT found, ignoring: " + includefile); WriteLog("SBT found, ignoring: " + includefile);
readParameters(*this); readParameters(*this);
} }
else else
{ {
if (Global.ParserLogIncludes) if (Global.ParserLogIncludes) {
{
WriteLog("including terrain: " + includefile); WriteLog("including terrain: " + includefile);
} }
mIncludeParser = std::make_unique<cParser>(includefile, buffer_FILE, mPath, LoadTraction, readParameters(*this)); mIncludeParser = std::make_shared<cParser>(includefile, buffer_FILE, mPath,
LoadTraction, readParameters(*this));
mIncludeParser->allowRandomIncludes = allowRandomIncludes; mIncludeParser->allowRandomIncludes = allowRandomIncludes;
mIncludeParser->autoclear(m_autoclear); mIncludeParser->autoclear(m_autoclear);
if (mIncludeParser->mSize <= 0) if (mIncludeParser->mSize <= 0)
@@ -347,31 +285,29 @@ std::string cParser::readToken(bool ToLower, const char *Break)
} }
} }
} }
} }
else else {
{ while( token != "end" ) {
while (token != "end") token = readToken( true ); // minimize risk of case mismatch on comparison
{ }
token = readToken(true); // minimize risk of case mismatch on comparison }
} token = readToken(ToLower, Break);
} }
token = readToken(ToLower, Break); else if( ( std::strcmp( Break, "\n\r" ) == 0 ) && ( token.compare( 0, 7, "include" ) == 0 ) ) {
} // HACK: if the parser reads full lines we expect this line to contain entire include directive, to make parsing easier
else if ((std::strcmp(Break, "\n\r") == 0) && (token.compare(0, 7, "include") == 0)) cParser includeparser( token.substr( 7 ) );
{ std::string includefile = allowRandomIncludes ? deserialize_random_set( includeparser ) : includeparser.readToken( ToLower ); // nazwa pliku
// HACK: if the parser reads full lines we expect this line to contain entire include directive, to make parsing easier replace_slashes(includefile);
cParser includeparser(token.substr(7)); if ((true == LoadTraction) ||
std::string includefile = allowRandomIncludes ? deserialize_random_set(includeparser) : includeparser.readToken(ToLower); // nazwa pliku ((false == contains(includefile, "tr/")) && (false == contains(includefile, "tra/"))))
replace_slashes(includefile);
if ((true == LoadTraction) || ((false == contains(includefile, "tr/")) && (false == contains(includefile, "tra/"))))
{ {
if (false == contains(includefile, "_ter.scm")) if (false == contains(includefile, "_ter.scm"))
{ {
if (Global.ParserLogIncludes) if (Global.ParserLogIncludes) {
{
// WriteLog("including: " + includefile); // WriteLog("including: " + includefile);
} }
mIncludeParser = std::make_unique<cParser>(includefile, buffer_FILE, mPath, LoadTraction, readParameters(includeparser)); mIncludeParser = std::make_shared<cParser>(
includefile, buffer_FILE, mPath, LoadTraction, readParameters(includeparser));
mIncludeParser->allowRandomIncludes = allowRandomIncludes; mIncludeParser->allowRandomIncludes = allowRandomIncludes;
mIncludeParser->autoclear(m_autoclear); mIncludeParser->autoclear(m_autoclear);
if (mIncludeParser->mSize <= 0) if (mIncludeParser->mSize <= 0)
@@ -388,58 +324,52 @@ std::string cParser::readToken(bool ToLower, const char *Break)
} }
else else
{ {
if (Global.ParserLogIncludes) if (Global.ParserLogIncludes) {
{
WriteLog("including terrain: " + includefile); WriteLog("including terrain: " + includefile);
} }
mIncludeParser = std::make_unique<cParser>(includefile, buffer_FILE, mPath, LoadTraction, readParameters(includeparser)); mIncludeParser =
std::make_shared<cParser>(includefile, buffer_FILE, mPath, LoadTraction,
readParameters(includeparser));
mIncludeParser->allowRandomIncludes = allowRandomIncludes; mIncludeParser->allowRandomIncludes = allowRandomIncludes;
mIncludeParser->autoclear(m_autoclear); mIncludeParser->autoclear(m_autoclear);
if (mIncludeParser->mSize <= 0) if (mIncludeParser->mSize <= 0)
{ {
ErrorLog("Bad include: can't open file \"" + includefile + "\""); ErrorLog("Bad include: can't open file \"" + includefile + "\"");
} }
}
}
} }
} }
token = readToken(ToLower, Break); token = readToken( ToLower, Break );
} }
// all done // all done
return token; return token;
} }
std::vector<std::string> cParser::readParameters(cParser &Input) std::vector<std::string> cParser::readParameters( cParser &Input ) {
{
std::vector<std::string> includeparameters; std::vector<std::string> includeparameters;
std::string parameter = Input.readToken(false); // w parametrach nie zmniejszamy std::string parameter = Input.readToken( false ); // w parametrach nie zmniejszamy
while ((parameter.empty() == false) && (parameter != "end")) while( ( parameter.empty() == false )
{ && ( parameter != "end" ) ) {
includeparameters.emplace_back(parameter); includeparameters.emplace_back( parameter );
parameter = Input.readToken(false); parameter = Input.readToken( false );
} }
return includeparameters; return includeparameters;
} }
std::string cParser::readQuotes(char const Quote) std::string cParser::readQuotes(char const Quote) { // read the stream until specified char or stream end
{ // read the stream until specified char or stream end std::string token = "";
std::string token; char c { 0 };
token.reserve(128);
char c{0};
bool escaped = false; bool escaped = false;
while (mStream->peek() != EOF) while( mStream->peek() != EOF ) { // get all chars until the quote mark
{ // get all chars until the quote mark
c = mStream->get(); c = mStream->get();
++mReadBytes;
if (escaped) if (escaped) {
{
escaped = false; escaped = false;
} }
else else {
{ if (c == '\\') {
if (c == '\\')
{
escaped = true; escaped = true;
continue; continue;
} }
@@ -450,153 +380,122 @@ std::string cParser::readQuotes(char const Quote)
if (c == '\n') if (c == '\n')
++mLine; // update line counter ++mLine; // update line counter
token += c; token += c;
} }
return token; return token;
} }
void cParser::skipComment(std::string const &Endmark) void cParser::skipComment( std::string const &Endmark ) { // pobieranie znaków aż do znalezienia znacznika końca
{ // pobieranie znaków aż do znalezienia znacznika końca std::string input = "";
std::string input; char c { 0 };
input.reserve(Endmark.size()); auto const endmarksize = Endmark.size();
char c{0}; while( mStream->peek() != EOF ) {
auto const endmarksize = Endmark.size(); // o ile nie koniec pliku
while (mStream->peek() != EOF) c = mStream->get(); // pobranie znaku
{ if( c == '\n' ) {
// o ile nie koniec pliku // update line counter
c = mStream->get(); // pobranie znaku ++mLine;
++mReadBytes; }
input += c;
if (c == '\n') if( input == Endmark ) // szukanie znacznika końca
{ break;
// update line counter if( input.size() >= endmarksize ) {
++mLine; // keep the read text short, to avoid pointless string re-allocations on longer comments
} input = input.substr( 1 );
input += c; }
if (input == Endmark) // szukanie znacznika końca }
break; return;
if (input.size() > endmarksize)
input.erase(0, input.size() - endmarksize);
}
return;
} }
bool cParser::findQuotes(std::string &String) bool cParser::findQuotes( std::string &String ) {
{
if (String.back() == '\"') if( String.back() == '\"' ) {
{
String.pop_back(); String.pop_back();
String += readQuotes(); String += readQuotes();
return true; return true;
} }
return false; return false;
} }
bool cParser::trimComments(std::string &String) bool cParser::trimComments(std::string &String)
{ {
for (auto const &comment : mComments) for (auto const &comment : mComments)
{ {
if (String.size() < comment.first.size()) if( String.size() < comment.first.size() ) { continue; }
{
continue;
}
if (String.compare(String.size() - comment.first.size(), comment.first.size(), comment.first) == 0) if (String.compare( String.size() - comment.first.size(), comment.first.size(), comment.first ) == 0)
{ {
skipComment(comment.second); skipComment(comment.second);
String.resize(String.rfind(comment.first)); String.resize(String.rfind(comment.first));
return true; return true;
} }
} }
return false; return false;
} }
void cParser::injectString(const std::string &str) void cParser::injectString(const std::string &str)
{ {
if (mIncludeParser) if (mIncludeParser) {
{
mIncludeParser->injectString(str); mIncludeParser->injectString(str);
} }
else else {
{ mIncludeParser = std::make_shared<cParser>( str, buffer_TEXT, "", LoadTraction, std::vector<std::string>(), allowRandomIncludes );
mIncludeParser = std::make_unique<cParser>(str, buffer_TEXT, "", LoadTraction, std::vector<std::string>(), allowRandomIncludes); mIncludeParser->autoclear( m_autoclear );
mIncludeParser->autoclear(m_autoclear);
} }
} }
int cParser::getProgress() const int cParser::getProgress() const
{ {
return mSize ? int(mReadBytes * 100 / mSize) : 0; return static_cast<int>( mStream->rdbuf()->pubseekoff(0, std::ios_base::cur) * 100 / mSize );
} }
int cParser::getFullProgress() const int cParser::getFullProgress() const {
{
int progress = getProgress(); int progress = getProgress();
if (mIncludeParser) if( mIncludeParser ) return progress + ( ( 100 - progress )*( mIncludeParser->getProgress() ) / 100 );
return progress + ((100 - progress) * (mIncludeParser->getProgress()) / 100); else return progress;
else
return progress;
} }
std::size_t cParser::countTokens(std::string const &Stream, std::string Path) std::size_t cParser::countTokens( std::string const &Stream, std::string Path ) {
{
return cParser(Stream, buffer_FILE, Path).count(); return cParser( Stream, buffer_FILE, Path ).count();
} }
std::size_t cParser::count() std::size_t cParser::count() {
{
std::string token; std::string token;
size_t count{0}; size_t count { 0 };
do do {
{ token = "";
token = ""; token = readToken( false );
token = readToken(false); ++count;
++count; } while( false == token.empty() );
} while (false == token.empty());
return count - 1; return count - 1;
} }
void cParser::addCommentStyle(std::string const &Commentstart, std::string const &Commentend) void cParser::addCommentStyle( std::string const &Commentstart, std::string const &Commentend ) {
{
mComments.emplace_back(commentmap::value_type(Commentstart, Commentend)); mComments.insert( commentmap::value_type(Commentstart, Commentend) );
} }
// returns name of currently open file, or empty string for text type stream // returns name of currently open file, or empty string for text type stream
std::string cParser::Name() const std::string
{ cParser::Name() const {
if (mIncludeParser) if( mIncludeParser ) { return mIncludeParser->Name(); }
{ else { return mPath + mFile; }
return mIncludeParser->Name();
}
else
{
return mPath + mFile;
}
} }
// returns number of currently processed line // returns number of currently processed line
std::size_t cParser::Line() const std::size_t
{ cParser::Line() const {
if (mIncludeParser) if( mIncludeParser ) { return mIncludeParser->Line(); }
{ else { return mLine; }
return mIncludeParser->Line();
}
else
{
return mLine;
}
} }
int cParser::LineMain() const int cParser::LineMain() const {
{
return mIncludeParser ? -1 : mLine; return mIncludeParser ? -1 : mLine;
} }

View File

@@ -104,22 +104,20 @@ class cParser //: public std::stringstream
bool trimComments( std::string &String ); bool trimComments( std::string &String );
std::size_t count(); std::size_t count();
// members: // members:
std::unordered_map<const char*, std::array<bool,256>> breakTables;
bool m_autoclear { true }; // unretrieved tokens are discarded when another read command is issued (legacy behaviour) bool m_autoclear { true }; // unretrieved tokens are discarded when another read command is issued (legacy behaviour)
bool LoadTraction { true }; // load traction? bool LoadTraction { true }; // load traction?
std::shared_ptr<std::istream> mStream; // relevant kind of buffer is attached on creation. std::shared_ptr<std::istream> mStream; // relevant kind of buffer is attached on creation.
std::string mFile; // name of the open file, if any std::string mFile; // name of the open file, if any
std::string mPath; // path to open stream, for relative path lookups. std::string mPath; // path to open stream, for relative path lookups.
std::size_t mReadBytes = 0;
std::streamoff mSize { 0 }; // size of open stream, for progress report. std::streamoff mSize { 0 }; // size of open stream, for progress report.
std::size_t mLine { 0 }; // currently processed line std::size_t mLine { 0 }; // currently processed line
bool mIncFile { false }; // the parser is processing an *.inc file bool mIncFile { false }; // the parser is processing an *.inc file
bool mFirstToken { true }; // processing first token in the current file; helper used when checking for utf bom bool mFirstToken { true }; // processing first token in the current file; helper used when checking for utf bom
using commentmap = std::vector<std::pair<std::string,std::string>>; typedef std::map<std::string, std::string> commentmap;
commentmap mComments { commentmap mComments {
commentmap::value_type( "/*", "*/" ), commentmap::value_type( "/*", "*/" ),
commentmap::value_type( "//", "\n" ) }; commentmap::value_type( "//", "\n" ) };
std::unique_ptr<cParser> mIncludeParser; // child class to handle include directives. std::shared_ptr<cParser> mIncludeParser; // child class to handle include directives.
std::vector<std::string> parameters; // parameter list for included file. std::vector<std::string> parameters; // parameter list for included file.
std::deque<std::string> tokens; std::deque<std::string> tokens;
}; };