Browse Source

Refactored AtomicPropositionLabelingParser.

- Not much to do here.
- Mostly comment corrections and code restructuring.

Next up: Parser.h/.cpp and the AutoParser.


Former-commit-id: 22d67dadb8
main
masawei 12 years ago
parent
commit
46e783c981
  1. 295
      src/parser/AtomicPropositionLabelingParser.cpp
  2. 31
      src/parser/AtomicPropositionLabelingParser.h
  3. 2
      src/parser/DeterministicModelParser.cpp
  4. 6
      src/parser/DeterministicSparseTransitionParser.h
  5. 2
      src/parser/MarkovAutomatonParser.cpp
  6. 2
      src/parser/NondeterministicModelParser.cpp
  7. 10
      test/functional/parser/ReadLabFileTest.cpp

295
src/parser/AtomicPropositionLabelingParser.cpp

@ -6,193 +6,164 @@
*/ */
#include "src/parser/AtomicPropositionLabelingParser.h" #include "src/parser/AtomicPropositionLabelingParser.h"
#include "src/parser/Parser.h"
#include <errno.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <locale.h>
#include <cstdlib>
#include <cstdio>
#include <cstring> #include <cstring>
#include <string> #include <string>
#include <clocale>
#include <iostream> #include <iostream>
#include "src/exceptions/WrongFormatException.h" #include "src/exceptions/WrongFormatException.h"
#include "src/exceptions/FileIoException.h" #include "src/exceptions/FileIoException.h"
#include "src/utility/OsDetection.h"
#include "log4cplus/logger.h" #include "log4cplus/logger.h"
#include "log4cplus/loggingmacros.h" #include "log4cplus/loggingmacros.h"
extern log4cplus::Logger logger; extern log4cplus::Logger logger;
namespace storm { namespace storm {
namespace parser { namespace parser {
storm::models::AtomicPropositionsLabeling AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(uint_fast64_t node_count, std::string const & filename) {
/*! // Open the given file.
* Reads a label file and puts the result in a labeling structure. if (!storm::parser::fileExistsAndIsReadable(filename.c_str())) {
* LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
* Labelings created with this method have to be freed with the delete operator. throw storm::exceptions::FileIoException() << "The supplied Labeling input file \"" << filename << "\" does not exist or is not readable by this process.";
* @param node_count the number of states. }
* @param filename input .lab file's name. // Find out about the used line endings.
* @return The pointer to the created labeling object. SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true);
*/ MappedFile file(filename.c_str());
storm::models::AtomicPropositionsLabeling AtomicPropositionLabelingParser(uint_fast64_t node_count, std::string const & filename) { char* buf = file.data;
/* // First pass: Count the number of propositions.
* Open file. // Convert the line endings into a string containing all whitespace characters, that separate words in the file.
*/ char separator[5];
if (!storm::parser::fileExistsAndIsReadable(filename.c_str())) { storm::parser::getMatchingSeparatorString(separator, sizeof(separator), lineEndings);
LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable."); bool foundDecl = false, foundEnd = false;
throw storm::exceptions::FileIoException() << "The supplied Labeling input file \"" << filename << "\" does not exist or is not readable by this process."; uint_fast32_t proposition_count = 0;
} size_t cnt = 0;
// Iterate over tokens until we hit #END or the end of the file.
/* while(buf[0] != '\0') {
* Find out about the used line endings. // Move the buffer pointer to the separator.
*/ buf += cnt;
SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true); // Get the number of characters until the next separator.
cnt = strcspn(buf, separator);
MappedFile file(filename.c_str()); if (cnt > 0) {
char* buf = file.data; // If the next token is #DECLARATION: Just skip it.
// If the next token is #END: Stop the search.
/* // Otherwise increase proposition_count.
* First run: obtain number of propositions. if (strncmp(buf, "#DECLARATION", cnt) == 0) {
*/ foundDecl = true;
char separator[5];// = " \r\n\t"; continue;
storm::parser::getMatchingSeparatorString(separator, sizeof(separator), lineEndings); } else if (strncmp(buf, "#END", cnt) == 0) {
foundEnd = true;
bool foundDecl = false, foundEnd = false; break;
uint_fast32_t proposition_count = 0; }
{ proposition_count++;
size_t cnt = 0; } else {
/* // If the next character is a separator, skip it.
* Iterate over tokens until we hit #END or end of file. buf++;
*/
while(buf[0] != '\0') {
buf += cnt;
cnt = strcspn(buf, separator); // position of next separator
if (cnt > 0) {
/*
* next token is #DECLARATION: just skip it
* next token is #END: stop search
* otherwise increase proposition_count
*/
if (strncmp(buf, "#DECLARATION", cnt) == 0) {
foundDecl = true;
continue;
} else if (strncmp(buf, "#END", cnt) == 0) {
foundEnd = true;
break;
} }
proposition_count++;
} else {
buf++; // next char is separator, one step forward
} }
}
/* // If #DECLARATION or #END have not been found, the file format is wrong.
* If #DECLARATION or #END were not found, the file format is wrong if (!(foundDecl && foundEnd)) {
*/ LOG4CPLUS_ERROR(logger, "Wrong file format in (" << filename << "). File header is corrupted.");
if (!(foundDecl && foundEnd)) { if (!foundDecl) LOG4CPLUS_ERROR(logger, "\tDid not find #DECLARATION token.");
LOG4CPLUS_ERROR(logger, "Wrong file format in (" << filename << "). File header is corrupted."); if (!foundEnd) LOG4CPLUS_ERROR(logger, "\tDid not find #END token.");
if (!foundDecl) LOG4CPLUS_ERROR(logger, "\tDid not find #DECLARATION token.");
if (!foundEnd) LOG4CPLUS_ERROR(logger, "\tDid not find #END token.");
throw storm::exceptions::WrongFormatException();
}
}
/*
* create labeling object with given node and proposition count
*/
storm::models::AtomicPropositionsLabeling labeling(node_count, proposition_count);
/*
* second run: add propositions and node labels to labeling
*
* first thing to do: reset file pointer
*/
buf = file.data;
{
/*
* load propositions
* As we already checked the file format, we can be a bit sloppy here...
*/
char proposition[128]; // buffer for proposition names
size_t cnt = 0;
do {
buf += cnt;
cnt = strcspn(buf, separator); // position of next separator
if (cnt >= sizeof(proposition)) {
/*
* if token is longer than our buffer, the following strncpy code might get risky...
*/
LOG4CPLUS_ERROR(logger, "Wrong file format in (" << filename << "). Atomic proposition with length > " << (sizeof(proposition)-1) << " was found.");
throw storm::exceptions::WrongFormatException(); throw storm::exceptions::WrongFormatException();
} else if (cnt > 0) {
/*
* next token is: #DECLARATION: just skip it
* next token is: #END: stop search
* otherwise: copy token to buffer, append trailing null byte and hand it to labeling
*/
if (strncmp(buf, "#DECLARATION", cnt) == 0) continue;
if (strncmp(buf, "#END", cnt) == 0) break;
strncpy(proposition, buf, cnt);
proposition[cnt] = '\0';
labeling.addAtomicProposition(proposition);
} else {
cnt = 1; // next char is separator, one step forward
} }
} while (cnt > 0); // Create labeling object with given node and proposition count.
/* storm::models::AtomicPropositionsLabeling labeling(node_count, proposition_count);
* Right here, the buf pointer is still pointing to our last token, // Second pass: Add propositions and node labels to labeling.
* i.e. to #END. We want to skip this one... // First thing to do: Reset the file pointer.
*/ buf = file.data;
buf += 4; // Prepare a buffer for proposition names.
} char proposition[128];
cnt = 0;
{ // Parse proposition names.
/* // As we already checked the file header, we know that #DECLARATION and #END are tokens in the character stream.
* now parse node label assignments while(buf[0] != '\0') {
*/ // Move the buffer pointer to the separator.
uint_fast64_t node; buf += cnt;
char proposition[128]; // The number of characters until the next separator.
size_t cnt;
/*
* iterate over nodes
*/
while (buf[0] != '\0') {
/*
* parse node number, then iterate over propositions
*/
node = checked_strtol(buf, &buf);
while ((buf[0] != '\r') && (buf[0] != '\n') && (buf[0] != '\0')) {
cnt = strcspn(buf, separator); cnt = strcspn(buf, separator);
if (cnt == 0) { if (cnt >= sizeof(proposition)) {
/* // if token is longer than our buffer, the following strncpy code might get risky...
* next char is a separator LOG4CPLUS_ERROR(logger, "Wrong file format in (" << filename << "). Atomic proposition with length > " << (sizeof(proposition)-1) << " was found.");
* if it's a newline, we continue with next node throw storm::exceptions::WrongFormatException();
* otherwise we skip it and try again } else if (cnt > 0) {
*/ // If the next token is #DECLARATION: Just skip it.
if (buf[0] == '\n' || buf[0] == '\r') break; if (strncmp(buf, "#DECLARATION", cnt) == 0) continue;
buf++; // If the next token is #END: Stop the search.
} else { if (strncmp(buf, "#END", cnt) == 0) break;
/* // Otherwise copy the token to the buffer, append a trailing null byte and hand it to labeling.
* copy proposition to buffer and add it to labeling
*/
strncpy(proposition, buf, cnt); strncpy(proposition, buf, cnt);
proposition[cnt] = '\0'; proposition[cnt] = '\0';
labeling.addAtomicPropositionToState(proposition, node); labeling.addAtomicProposition(proposition);
buf += cnt; } else {
// The next character is a separator, thus move one step forward.
buf++;
} }
} }
buf = storm::parser::trimWhitespaces(buf); // At this point, the pointer buf is still pointing to our last token, i.e. to #END.
// We want to skip it.
buf += 4;
uint_fast64_t node;
cnt = 0;
// Now parse the assignments of labels to nodes.
while (buf[0] != '\0') {
// Parse the node number and iterate over its labels (atomic propositions).
// Stop at the end of the line.
node = checked_strtol(buf, &buf);
while ((buf[0] != '\r') && (buf[0] != '\n') && (buf[0] != '\0')) {
cnt = strcspn(buf, separator);
if (cnt == 0) {
// The next character is a separator.
// If it is a line separator, we continue with next node.
// Otherwise, we skip it and try again.
if (buf[0] == '\n' || buf[0] == '\r') break;
buf++;
} else {
// Copy the label to the buffer, null terminate it and add it to labeling.
strncpy(proposition, buf, cnt);
proposition[cnt] = '\0';
labeling.addAtomicPropositionToState(proposition, node);
buf += cnt;
}
}
buf = trimWhitespaces(buf);
}
return labeling;
} }
}
return labeling;
}
} // namespace parser } // namespace parser
} // namespace storm } // namespace storm

31
src/parser/AtomicPropositionLabelingParser.h

@ -1,23 +1,28 @@
#ifndef STORM_PARSER_LABPARSER_H_ #ifndef STORM_PARSER_ATOMICPROPOSITIONLABELINGPARSER_H_
#define STORM_PARSER_LABPARSER_H_ #define STORM_PARSER_ATOMICPROPOSITIONLABELINGPARSER_H_
#include "src/models/AtomicPropositionsLabeling.h" #include "src/models/AtomicPropositionsLabeling.h"
#include <cstdint> #include <cstdint>
#include "src/parser/Parser.h" namespace storm {
namespace parser {
#include <memory> class AtomicPropositionLabelingParser {
namespace storm { public:
namespace parser { /*
* Reads a label file and puts the result in an AtomicPropositionsLabeling object.
*
* @param node_count The number of states of the model to be labeled.
* @param filename The path and name of the labeling (.lab) file.
* @return The parsed labeling as an AtomicPropositionsLabeling object.
*/
static storm::models::AtomicPropositionsLabeling parseAtomicPropositionLabeling(uint_fast64_t node_count, std::string const &filename);
/*! };
* @brief Load label file and return initialized AtomicPropositionsLabeling object.
*
*/
storm::models::AtomicPropositionsLabeling AtomicPropositionLabelingParser(uint_fast64_t node_count, std::string const &filename);
} // namespace parser } // namespace parser
} // namespace storm } // namespace storm
#endif /* STORM_PARSER_LABPARSER_H_ */ #endif /* STORM_PARSER_ATOMICPROPOSITIONLABELINGPARSER_H_ */

2
src/parser/DeterministicModelParser.cpp

@ -33,7 +33,7 @@ DeterministicModelParser::Result DeterministicModelParser::parseDeterministicMod
uint_fast64_t stateCount = resultTransitionSystem.getColumnCount(); uint_fast64_t stateCount = resultTransitionSystem.getColumnCount();
uint_fast64_t rowCount = resultTransitionSystem.getRowCount(); uint_fast64_t rowCount = resultTransitionSystem.getRowCount();
storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser(stateCount, labelingFile))); storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(stateCount, labelingFile)));
DeterministicModelParser::Result result(std::move(resultTransitionSystem), std::move(labeling)); DeterministicModelParser::Result result(std::move(resultTransitionSystem), std::move(labeling));

6
src/parser/DeterministicSparseTransitionParser.h

@ -1,5 +1,5 @@
#ifndef STORM_PARSER_TRAPARSER_H_ #ifndef STORM_PARSER_DETERMINISTICSPARSETRANSITIONPARSER_H_
#define STORM_PARSER_TRAPARSER_H_ #define STORM_PARSER_DETERMINISTICSPARSETRANSITIONPARSER_H_
#include "src/storage/SparseMatrix.h" #include "src/storage/SparseMatrix.h"
#include "src/parser/Parser.h" #include "src/parser/Parser.h"
@ -82,4 +82,4 @@ private:
} // namespace storm } // namespace storm
#endif /* STORM_PARSER_TRAPARSER_H_ */ #endif /* STORM_PARSER_DETERMINISTICSPARSETRANSITIONPARSER_H_ */

2
src/parser/MarkovAutomatonParser.cpp

@ -16,7 +16,7 @@ storm::models::MarkovAutomaton<double> MarkovAutomatonParser::parseMarkovAutomat
storm::storage::SparseMatrix<double> transitionMatrix(transitionResult.transitionMatrixBuilder.build(0,0)); storm::storage::SparseMatrix<double> transitionMatrix(transitionResult.transitionMatrixBuilder.build(0,0));
// Parse the state labeling. // Parse the state labeling.
storm::models::AtomicPropositionsLabeling resultLabeling(storm::parser::AtomicPropositionLabelingParser(transitionMatrix.getColumnCount(), labelingFilename)); storm::models::AtomicPropositionsLabeling resultLabeling(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(transitionMatrix.getColumnCount(), labelingFilename));
// If given, parse the state rewards file. // If given, parse the state rewards file.
boost::optional<std::vector<double>> stateRewards; boost::optional<std::vector<double>> stateRewards;

2
src/parser/NondeterministicModelParser.cpp

@ -35,7 +35,7 @@ namespace storm {
uint_fast64_t stateCount = transitions.getColumnCount(); uint_fast64_t stateCount = transitions.getColumnCount();
uint_fast64_t rowCount = transitions.getRowCount(); uint_fast64_t rowCount = transitions.getRowCount();
storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser(stateCount, labelingFile))); storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(stateCount, labelingFile)));
Result result(std::move(transitions), std::move(transitionParserResult.rowMapping), std::move(labeling)); Result result(std::move(transitions), std::move(transitionParserResult.rowMapping), std::move(labeling));

10
test/functional/parser/ReadLabFileTest.cpp

@ -16,14 +16,14 @@
TEST(ReadLabFileTest, NonExistingFileTest) { TEST(ReadLabFileTest, NonExistingFileTest) {
// No matter what happens, please do NOT create a file with the name "nonExistingFile.not"! // No matter what happens, please do NOT create a file with the name "nonExistingFile.not"!
ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser(0,STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException); ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(0,STORM_CPP_TESTS_BASE_PATH "/nonExistingFile.not"), storm::exceptions::FileIoException);
} }
TEST(ReadLabFileTest, ParseTest) { TEST(ReadLabFileTest, ParseTest) {
// This test is based on a test case from the original MRMC. // This test is based on a test case from the original MRMC.
// Parsing the file // Parsing the file
storm::models::AtomicPropositionsLabeling labeling = storm::parser::AtomicPropositionLabelingParser(12, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/pctl_general_input_01.lab"); storm::models::AtomicPropositionsLabeling labeling = storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(12, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/pctl_general_input_01.lab");
// Checking whether all propositions are in the labelling // Checking whether all propositions are in the labelling
@ -79,14 +79,14 @@ TEST(ReadLabFileTest, ParseTest) {
} }
TEST(ReadLabFileTest, WrongHeaderTest1) { TEST(ReadLabFileTest, WrongHeaderTest1) {
ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/wrong_format_header1.lab"), storm::exceptions::WrongFormatException); ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/wrong_format_header1.lab"), storm::exceptions::WrongFormatException);
} }
TEST(ReadLabFileTest, WrongHeaderTest2) { TEST(ReadLabFileTest, WrongHeaderTest2) {
ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/wrong_format_header2.lab"), storm::exceptions::WrongFormatException); ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/wrong_format_header2.lab"), storm::exceptions::WrongFormatException);
} }
TEST(ReadLabFileTest, WrongPropositionTest) { TEST(ReadLabFileTest, WrongPropositionTest) {
ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/wrong_format_proposition.lab"), storm::exceptions::WrongFormatException); ASSERT_THROW(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(3, STORM_CPP_TESTS_BASE_PATH "/functional/parser/lab_files/wrong_format_proposition.lab"), storm::exceptions::WrongFormatException);
} }
|||||||
100:0
Loading…
Cancel
Save