Browse Source
Second part of the refactoring of Parser.cpp/.h
Second part of the refactoring of Parser.cpp/.h
- Eliminated the need for SupportedLineEndings (I hope...should work on all os, but have only tested this on linux)
- Moved fileExistsAndIsReadable to MappedFile
- Removed scanForModelHint and replaced it with its contents at the one point where is was used in the AutoParser
- Moved and renamed remaining part of Parser.cpp/.h to src/utility/cstring.cpp/.h
|- New namespace of the cstring manipulation functions is storm::utility::cstring
|- Used a using namespace storm::utility::cstring to eliminate the full namespace specification within the needing parsers. This keeps the code readable.
- Threw out some unnessesary includes.
Next up: Commenting and making things look nice.
Former-commit-id: c983d1e1a2
tempestpy_adaptions
masawei
11 years ago
22 changed files with 246 additions and 433 deletions
-
35src/parser/AtomicPropositionLabelingParser.cpp
-
19src/parser/AutoParser.cpp
-
8src/parser/AutoParser.h
-
2src/parser/CslParser.h
-
1src/parser/DeterministicModelParser.h
-
18src/parser/DeterministicSparseTransitionParser.cpp
-
4src/parser/DeterministicSparseTransitionParser.h
-
1src/parser/LtlParser.h
-
8src/parser/MappedFile.cpp
-
6src/parser/MappedFile.h
-
38src/parser/MarkovAutomatonSparseTransitionParser.cpp
-
7src/parser/MarkovAutomatonSparseTransitionParser.h
-
1src/parser/NondeterministicModelParser.h
-
23src/parser/NondeterministicSparseTransitionParser.cpp
-
4src/parser/NondeterministicSparseTransitionParser.h
-
253src/parser/Parser.cpp
-
93src/parser/Parser.h
-
2src/parser/PrctlParser.h
-
6src/parser/SparseStateRewardParser.cpp
-
95src/utility/cstring.cpp
-
53src/utility/cstring.h
-
2test/functional/parser/MarkovAutomatonParserTest.cpp
@ -1,253 +0,0 @@ |
|||
#include "src/parser/Parser.h"
|
|||
|
|||
#include <fcntl.h>
|
|||
#include <iostream>
|
|||
#include <fstream>
|
|||
#include <cstring>
|
|||
#include <string>
|
|||
#include <cerrno>
|
|||
|
|||
#include <boost/integer/integer_mask.hpp>
|
|||
#include "src/exceptions/FileIoException.h"
|
|||
#include "src/exceptions/WrongFormatException.h"
|
|||
#include "src/utility/OsDetection.h"
|
|||
#include "src/parser/MappedFile.h"
|
|||
|
|||
#include "log4cplus/logger.h"
|
|||
#include "log4cplus/loggingmacros.h"
|
|||
extern log4cplus::Logger logger; |
|||
|
|||
namespace storm { |
|||
|
|||
namespace parser { |
|||
|
|||
/*!
|
|||
* Calls strtol() internally and checks if the new pointer is different |
|||
* from the original one, i.e. if str != *end. If they are the same, a |
|||
* storm::exceptions::WrongFormatException will be thrown. |
|||
* @param str String to parse |
|||
* @param end New pointer will be written there |
|||
* @return Result of strtol() |
|||
*/ |
|||
uint_fast64_t checked_strtol(const char* str, char** end) { |
|||
uint_fast64_t res = strtol(str, end, 10); |
|||
if (str == *end) { |
|||
LOG4CPLUS_ERROR(logger, "Error while parsing integer. Next input token is not a number."); |
|||
LOG4CPLUS_ERROR(logger, "\tUpcoming input is: \"" << std::string(str, 0, 16) << "\""); |
|||
throw storm::exceptions::WrongFormatException("Error while parsing integer. Next input token is not a number."); |
|||
} |
|||
return res; |
|||
} |
|||
|
|||
/*!
|
|||
* Calls strtod() internally and checks if the new pointer is different |
|||
* from the original one, i.e. if str != *end. If they are the same, a |
|||
* storm::exceptions::WrongFormatException will be thrown. |
|||
* @param str String to parse |
|||
* @param end New pointer will be written there |
|||
* @return Result of strtod() |
|||
*/ |
|||
double checked_strtod(const char* str, char** end) { |
|||
double res = strtod(str, end); |
|||
if (str == *end) { |
|||
LOG4CPLUS_ERROR(logger, "Error while parsing floating point. Next input token is not a number."); |
|||
LOG4CPLUS_ERROR(logger, "\tUpcoming input is: \"" << std::string(str, 0, 16) << "\""); |
|||
throw storm::exceptions::WrongFormatException("Error while parsing floating point. Next input token is not a number."); |
|||
} |
|||
return res; |
|||
} |
|||
|
|||
/*!
|
|||
* @brief Tests whether the given file exists and is readable. |
|||
* @return True iff the file exists and is readable. |
|||
*/ |
|||
bool fileExistsAndIsReadable(const char* fileName) { |
|||
std::ifstream fin(fileName); |
|||
bool returnValue = !fin.fail(); |
|||
return returnValue; |
|||
} |
|||
|
|||
/*!
|
|||
* Skips all numbers, letters and special characters. |
|||
* Returns a pointer to the first char that is a whitespace. |
|||
* @param buf The string buffer to operate on. |
|||
* @return A pointer to the first whitespace character. |
|||
*/ |
|||
char* skipWord(char* buf){ |
|||
while((*buf != ' ') && (*buf != '\t') && (*buf != '\n') && (*buf != '\r')) buf++; |
|||
return buf; |
|||
} |
|||
|
|||
/*!
|
|||
* Skips spaces, tabs, newlines and carriage returns. Returns a pointer |
|||
* to first char that is not a whitespace. |
|||
* @param buf The string buffer to operate on. |
|||
* @return A pointer to the first non-whitespace character. |
|||
*/ |
|||
char* trimWhitespaces(char* buf) { |
|||
while ((*buf == ' ') || (*buf == '\t') || (*buf == '\n') || (*buf == '\r')) buf++; |
|||
return buf; |
|||
} |
|||
|
|||
/*!
|
|||
* @briefs Analyzes the given file and tries to find out the used file endings. |
|||
*/ |
|||
SupportedLineEndings findUsedLineEndings(std::string const& fileName, bool throwOnUnsupported) { |
|||
MappedFile fileMap(fileName.c_str()); |
|||
char* buf = nullptr; |
|||
char* const bufferEnd = fileMap.dataend; |
|||
|
|||
for (buf = fileMap.data; buf != bufferEnd; ++buf) { |
|||
if (*buf == '\r') { |
|||
// check for following \n
|
|||
if (((buf + sizeof(char)) < bufferEnd) && (*(buf + sizeof(char)) == '\n')) { |
|||
return SupportedLineEndings::SlashRN; |
|||
} |
|||
return SupportedLineEndings::SlashR; |
|||
} else if (*buf == '\n') { |
|||
return SupportedLineEndings::SlashN; |
|||
} |
|||
} |
|||
|
|||
if (throwOnUnsupported) { |
|||
LOG4CPLUS_ERROR(logger, "Error while parsing \"" << fileName << "\": Unsupported or unknown line-endings. Please use either of \\r, \\n or \\r\\n"); |
|||
throw storm::exceptions::WrongFormatException() << "Error while parsing \"" << fileName << "\": Unsupported or unknown line-endings. Please use either of \\r, \\n or \\r\\n"; |
|||
} |
|||
LOG4CPLUS_WARN(logger, "Error while parsing \"" << fileName << "\": Unsupported or unknown line-endings. Please use either of \\r, \\n or \\r\\n"); |
|||
|
|||
return SupportedLineEndings::Unsupported; |
|||
} |
|||
|
|||
/*!
|
|||
* @brief Encapsulates the usage of function @strcspn to forward to the end of the line (next char is the newline character). |
|||
*/ |
|||
char* forwardToLineEnd(char* buffer, SupportedLineEndings lineEndings) { |
|||
switch (lineEndings) { |
|||
case SupportedLineEndings::SlashN: |
|||
return buffer + strcspn(buffer, "\n\0"); |
|||
break; |
|||
case SupportedLineEndings::SlashR: |
|||
return buffer + strcspn(buffer, "\r\0"); |
|||
break; |
|||
case SupportedLineEndings::SlashRN: |
|||
return buffer + strcspn(buffer, "\r\0"); |
|||
break; |
|||
default: |
|||
case SupportedLineEndings::Unsupported: |
|||
// This Line will never be reached as the Parser would have thrown already.
|
|||
throw; |
|||
break; |
|||
} |
|||
return nullptr; |
|||
} |
|||
|
|||
/*!
|
|||
* @brief Encapsulates the usage of function @strchr to forward to the next line |
|||
*/ |
|||
char* forwardToNextLine(char* buffer, SupportedLineEndings lineEndings) { |
|||
switch (lineEndings) { |
|||
case SupportedLineEndings::SlashN: |
|||
return strchr(buffer, '\n') + 1; |
|||
break; |
|||
case SupportedLineEndings::SlashR: |
|||
return strchr(buffer, '\r') + 1; |
|||
break; |
|||
case SupportedLineEndings::SlashRN: |
|||
return strchr(buffer, '\r') + 2; |
|||
break; |
|||
default: |
|||
case SupportedLineEndings::Unsupported: |
|||
// This Line will never be reached as the Parser would have thrown already.
|
|||
throw; |
|||
break; |
|||
} |
|||
return nullptr; |
|||
} |
|||
|
|||
/*!
|
|||
* @brief Encapsulates the usage of function @sscanf to scan for the model type hint |
|||
* @param targetBuffer The Target for the hint, must be at least 64 bytes long |
|||
* @param buffer The Source Buffer from which the Model Hint will be read |
|||
*/ |
|||
void scanForModelHint(char* targetBuffer, uint_fast64_t targetBufferSize, char const* buffer, SupportedLineEndings lineEndings) { |
|||
if (targetBufferSize <= 4) { |
|||
throw; |
|||
} |
|||
switch (lineEndings) { |
|||
case SupportedLineEndings::SlashN: |
|||
#ifdef WINDOWS
|
|||
sscanf_s(buffer, "%60s\n", targetBuffer, targetBufferSize); |
|||
#else
|
|||
sscanf(buffer, "%60s\n", targetBuffer); |
|||
#endif
|
|||
break; |
|||
case SupportedLineEndings::SlashR: |
|||
#ifdef WINDOWS
|
|||
sscanf_s(buffer, "%60s\r", targetBuffer, sizeof(targetBufferSize)); |
|||
#else
|
|||
sscanf(buffer, "%60s\r", targetBuffer); |
|||
#endif
|
|||
break; |
|||
case SupportedLineEndings::SlashRN: |
|||
#ifdef WINDOWS
|
|||
sscanf_s(buffer, "%60s\r\n", targetBuffer, sizeof(targetBufferSize)); |
|||
#else
|
|||
sscanf(buffer, "%60s\r\n", targetBuffer); |
|||
#endif
|
|||
break; |
|||
default: |
|||
case SupportedLineEndings::Unsupported: |
|||
// This Line will never be reached as the Parser would have thrown already.
|
|||
throw; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
/*!
|
|||
* @brief Returns the matching Separator-String in the format of "BLANK\t\NEWLINESYMBOL(S)\0 |
|||
*/ |
|||
void getMatchingSeparatorString(char* targetBuffer, uint_fast64_t targetBufferSize, SupportedLineEndings lineEndings) { |
|||
if (targetBufferSize < 5) { |
|||
LOG4CPLUS_ERROR(logger, "getMatchingSeparatorString: The passed Target Buffer is too small."); |
|||
throw; |
|||
} |
|||
switch (lineEndings) { |
|||
case SupportedLineEndings::SlashN: { |
|||
char source[] = " \n\t"; |
|||
#ifdef WINDOWS
|
|||
strncpy(targetBuffer, targetBufferSize, source, sizeof(source)); |
|||
#else
|
|||
strncpy(targetBuffer, source, targetBufferSize); |
|||
#endif
|
|||
break; |
|||
} |
|||
case SupportedLineEndings::SlashR: { |
|||
char source[] = " \r\t"; |
|||
#ifdef WINDOWS
|
|||
strncpy(targetBuffer, targetBufferSize, source, sizeof(source)); |
|||
#else
|
|||
strncpy(targetBuffer, source, targetBufferSize); |
|||
#endif
|
|||
break; |
|||
} |
|||
case SupportedLineEndings::SlashRN: { |
|||
char source[] = " \r\n\t"; |
|||
#ifdef WINDOWS
|
|||
strncpy(targetBuffer, targetBufferSize, source, sizeof(source)); |
|||
#else
|
|||
strncpy(targetBuffer, source, targetBufferSize); |
|||
#endif
|
|||
break; |
|||
} |
|||
default: |
|||
case SupportedLineEndings::Unsupported: |
|||
// This Line will never be reached as the Parser would have thrown already.
|
|||
LOG4CPLUS_ERROR(logger, "getMatchingSeparatorString: The passed lineEndings were Unsupported. Check your input file."); |
|||
throw; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
} // namespace parser
|
|||
|
|||
} // namespace storm
|
@ -1,93 +0,0 @@ |
|||
/* |
|||
* Parser.h |
|||
* |
|||
* Created on: 21.11.2012 |
|||
* Author: Gereon Kremer |
|||
*/ |
|||
|
|||
#ifndef STORM_PARSER_PARSER_H_ |
|||
#define STORM_PARSER_PARSER_H_ |
|||
|
|||
#include "src/utility/OsDetection.h" |
|||
|
|||
#include <sys/stat.h> |
|||
#include <vector> |
|||
#include <string> |
|||
|
|||
namespace storm { |
|||
|
|||
/*! |
|||
* @brief Contains all file parsers and helper classes. |
|||
* |
|||
* This namespace contains everything needed to load data files (like |
|||
* atomic propositions, transition systems, formulas, etc.) including |
|||
* methods for efficient file access (see MappedFile). |
|||
*/ |
|||
namespace parser { |
|||
|
|||
/*! |
|||
* @brief Parses integer and checks, if something has been parsed. |
|||
*/ |
|||
uint_fast64_t checked_strtol(const char* str, char** end); |
|||
|
|||
/*! |
|||
* @brief Parses floating point and checks, if something has been parsed. |
|||
*/ |
|||
double checked_strtod(const char* str, char** end); |
|||
|
|||
/*! |
|||
* @brief Skips all non whitespace characters until the next whitespace. |
|||
*/ |
|||
char* skipWord(char* buf); |
|||
|
|||
/*! |
|||
* @brief Skips common whitespaces in a string. |
|||
*/ |
|||
char* trimWhitespaces(char* buf); |
|||
|
|||
/*! |
|||
* @brief Tests whether the given file exists and is readable. |
|||
*/ |
|||
bool fileExistsAndIsReadable(const char* fileName); |
|||
|
|||
/*! |
|||
* @brief Enum Class Type containing all supported file endings. |
|||
*/ |
|||
enum class SupportedLineEndings : unsigned short { |
|||
Unsupported = 0, |
|||
SlashR, |
|||
SlashN, |
|||
SlashRN |
|||
}; |
|||
|
|||
/*! |
|||
* @briefs Analyzes the given file and tries to find out the used line endings. |
|||
*/ |
|||
storm::parser::SupportedLineEndings findUsedLineEndings(std::string const& fileName, bool throwOnUnsupported = false); |
|||
|
|||
/*! |
|||
* @brief Encapsulates the usage of function @strcspn to forward to the end of the line (next char is the newline character). |
|||
*/ |
|||
char* forwardToLineEnd(char* buffer, storm::parser::SupportedLineEndings lineEndings); |
|||
|
|||
/*! |
|||
* @brief Encapsulates the usage of function @strchr to forward to the next line |
|||
*/ |
|||
char* forwardToNextLine(char* buffer, storm::parser::SupportedLineEndings lineEndings); |
|||
|
|||
/*! |
|||
* @brief Encapsulates the usage of function @sscanf to scan for the model type hint |
|||
* @param targetBuffer The Target for the hint, should be at least 64 bytes long |
|||
* @param buffer The Source Buffer from which the Model Hint will be read |
|||
*/ |
|||
void scanForModelHint(char* targetBuffer, uint_fast64_t targetBufferSize, char const* buffer, storm::parser::SupportedLineEndings lineEndings); |
|||
|
|||
/*! |
|||
* @brief Returns the matching Separator-String in the format of "BLANK\t\NEWLINESYMBOL(S)\0 |
|||
*/ |
|||
void getMatchingSeparatorString(char* targetBuffer, uint_fast64_t targetBufferSize, storm::parser::SupportedLineEndings lineEndings); |
|||
|
|||
} // namespace parser |
|||
} // namespace storm |
|||
|
|||
#endif /* STORM_PARSER_PARSER_H_ */ |
@ -0,0 +1,95 @@ |
|||
#include "src/utility/cstring.h"
|
|||
|
|||
#include <cstring>
|
|||
|
|||
#include "src/exceptions/WrongFormatException.h"
|
|||
|
|||
#include "log4cplus/logger.h"
|
|||
#include "log4cplus/loggingmacros.h"
|
|||
extern log4cplus::Logger logger; |
|||
|
|||
namespace storm { |
|||
|
|||
namespace utility { |
|||
|
|||
namespace cstring { |
|||
|
|||
/*!
|
|||
* Calls strtol() internally and checks if the new pointer is different |
|||
* from the original one, i.e. if str != *end. If they are the same, a |
|||
* storm::exceptions::WrongFormatException will be thrown. |
|||
* @param str String to parse |
|||
* @param end New pointer will be written there |
|||
* @return Result of strtol() |
|||
*/ |
|||
uint_fast64_t checked_strtol(const char* str, char** end) { |
|||
uint_fast64_t res = strtol(str, end, 10); |
|||
if (str == *end) { |
|||
LOG4CPLUS_ERROR(logger, "Error while parsing integer. Next input token is not a number."); |
|||
LOG4CPLUS_ERROR(logger, "\tUpcoming input is: \"" << std::string(str, 0, 16) << "\""); |
|||
throw storm::exceptions::WrongFormatException("Error while parsing integer. Next input token is not a number."); |
|||
} |
|||
return res; |
|||
} |
|||
|
|||
/*!
|
|||
* Calls strtod() internally and checks if the new pointer is different |
|||
* from the original one, i.e. if str != *end. If they are the same, a |
|||
* storm::exceptions::WrongFormatException will be thrown. |
|||
* @param str String to parse |
|||
* @param end New pointer will be written there |
|||
* @return Result of strtod() |
|||
*/ |
|||
double checked_strtod(const char* str, char** end) { |
|||
double res = strtod(str, end); |
|||
if (str == *end) { |
|||
LOG4CPLUS_ERROR(logger, "Error while parsing floating point. Next input token is not a number."); |
|||
LOG4CPLUS_ERROR(logger, "\tUpcoming input is: \"" << std::string(str, 0, 16) << "\""); |
|||
throw storm::exceptions::WrongFormatException("Error while parsing floating point. Next input token is not a number."); |
|||
} |
|||
return res; |
|||
} |
|||
|
|||
/*!
|
|||
* Skips all numbers, letters and special characters. |
|||
* Returns a pointer to the first char that is a whitespace. |
|||
* @param buf The string buffer to operate on. |
|||
* @return A pointer to the first whitespace character. |
|||
*/ |
|||
char* skipWord(char* buf){ |
|||
while(!isspace(*buf) && *buf != '\0') buf++; |
|||
return buf; |
|||
} |
|||
|
|||
/*!
|
|||
* Skips spaces, tabs, newlines and carriage returns. Returns a pointer |
|||
* to first char that is not a whitespace. |
|||
* @param buf The string buffer to operate on. |
|||
* @return A pointer to the first non-whitespace character. |
|||
*/ |
|||
char* trimWhitespaces(char* buf) { |
|||
while (isspace(*buf)) buf++; |
|||
return buf; |
|||
} |
|||
|
|||
/*!
|
|||
* @brief Encapsulates the usage of function @strcspn to forward to the end of the line (next char is the newline character). |
|||
*/ |
|||
char* forwardToLineEnd(char* buffer) { |
|||
return buffer + strcspn(buffer, "\n\r\0"); |
|||
} |
|||
|
|||
/*!
|
|||
* @brief Encapsulates the usage of function @strchr to forward to the next line |
|||
*/ |
|||
char* forwardToNextLine(char* buffer) { |
|||
char* lineEnd = forwardToLineEnd(buffer); |
|||
while((*lineEnd == '\n') || (*lineEnd == '\r')) lineEnd++; |
|||
return lineEnd; |
|||
} |
|||
|
|||
} // namespace cstring
|
|||
|
|||
} // namespace utility
|
|||
|
|||
} // namespace storm
|
@ -0,0 +1,53 @@ |
|||
/* |
|||
* cstring.h |
|||
* |
|||
* Created on: 30.01.2014 |
|||
* Author: Manuel Sascha Weiand |
|||
*/ |
|||
|
|||
#ifndef STORM_UTILITY_CSTRING_H_ |
|||
#define STORM_UTILITY_CSTRING_H_ |
|||
|
|||
#include <cstdint> |
|||
|
|||
namespace storm { |
|||
namespace utility { |
|||
namespace cstring { |
|||
|
|||
/*! |
|||
* @brief Parses integer and checks, if something has been parsed. |
|||
*/ |
|||
uint_fast64_t checked_strtol(const char* str, char** end); |
|||
|
|||
/*! |
|||
* @brief Parses floating point and checks, if something has been parsed. |
|||
*/ |
|||
double checked_strtod(const char* str, char** end); |
|||
|
|||
/*! |
|||
* @brief Skips all non whitespace characters until the next whitespace. |
|||
*/ |
|||
char* skipWord(char* buf); |
|||
|
|||
/*! |
|||
* @brief Skips common whitespaces in a string. |
|||
*/ |
|||
char* trimWhitespaces(char* buf); |
|||
|
|||
/*! |
|||
* @brief Encapsulates the usage of function @strcspn to forward to the end of the line (next char is the newline character). |
|||
*/ |
|||
char* forwardToLineEnd(char* buffer); |
|||
|
|||
/*! |
|||
* @brief Encapsulates the usage of function @strchr to forward to the next line |
|||
* |
|||
* Note: All lines after the current, which do not contain any characters are skipped. |
|||
*/ |
|||
char* forwardToNextLine(char* buffer); |
|||
|
|||
} // namespace cstring |
|||
} // namespace utility |
|||
} // namespace storm |
|||
|
|||
#endif /* STORM_UTILITY_CSTRING_H_ */ |
Write
Preview
Loading…
Cancel
Save
Reference in new issue