Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
AtomicPropositionLabelingParser.cpp
Go to the documentation of this file.
2
3#include <cstring>
4#include <iostream>
5#include <string>
6
12
13namespace storm {
14namespace parser {
15
16using namespace storm::utility::cstring;
17
19 // Open the given file.
20 MappedFile file(filename.c_str());
21 char const* buf = file.getData();
22
23 // First pass: Check whether we find declaration and end.
24 // TODO this could be skipped.
25 bool foundDecl = false, foundEnd = false;
26 size_t cnt = 0;
27
28 // Iterate over tokens until we hit #END or the end of the file.
29 while (buf[0] != '\0') {
30 // Move the buffer to the beginning of the next word.
31 buf += cnt;
32 buf = trimWhitespaces(buf);
33
34 // Get the number of characters until the next separator.
35 cnt = skipWord(buf) - buf;
36 if (cnt > 0) {
37 // If the next token is #DECLARATION: Just skip it.
38 // If the next token is #END: Stop the search.
39 // Otherwise increase proposition_count.
40 if (strncmp(buf, "#DECLARATION", cnt) == 0) {
41 foundDecl = true;
42 continue;
43 } else if (strncmp(buf, "#END", cnt) == 0) {
44 foundEnd = true;
45 break;
46 }
47 }
48 }
49
50 // If #DECLARATION or #END have not been found, the file format is wrong.
51 STORM_LOG_THROW(foundDecl, storm::exceptions::WrongFormatException,
52 "Error while parsing " << filename << ": File header is corrupted (#DECLARATION missing - case sensitive).");
53 STORM_LOG_THROW(foundEnd, storm::exceptions::WrongFormatException,
54 "Error while parsing " << filename << ": File header is corrupted (#END missing - case sensitive).");
55
56 // Create labeling object with given node and proposition count.
57 storm::models::sparse::StateLabeling labeling(stateCount);
58
59 // Second pass: Add propositions and node labels to labeling.
60 // First thing to do: Reset the file pointer.
61 buf = file.getData();
62
63 // Prepare a buffer for proposition names.
64 char proposition[128];
65 cnt = 0;
66
67 // Parse proposition names.
68 // As we already checked the file header, we know that #DECLARATION and #END are tokens in the character stream.
69 while (buf[0] != '\0') {
70 // Move the buffer to the beginning of the next word.
71 buf += cnt;
72 buf = trimWhitespaces(buf);
73
74 // Get the number of characters until the next separator.
75 cnt = skipWord(buf) - buf;
76
77 if (cnt >= sizeof(proposition)) {
78 // if token is longer than our buffer, the following strncpy code might get risky...
79 STORM_LOG_THROW(false, storm::exceptions::WrongFormatException,
80 "Error while parsing " << filename << ": Atomic proposition with length > " << (sizeof(proposition) - 1) << " was found.");
81
82 } else if (cnt > 0) {
83 // If the next token is #DECLARATION: Just skip it.
84 if (strncmp(buf, "#DECLARATION", cnt) == 0) {
85 continue;
86 }
87
88 // If the next token is #END: Stop the search.
89 if (strncmp(buf, "#END", cnt) == 0) {
90 break;
91 }
92
93 // Otherwise copy the token to the buffer, append a trailing null byte and hand it to labeling.
94 strncpy(proposition, buf, cnt);
95 proposition[cnt] = '\0';
96 labeling.addLabel(proposition);
97 }
98 }
99
100 // At this point, the pointer buf is still pointing to our last token, i.e. to #END.
101 // We want to skip it.
102 buf += 4;
103
104 // Now eliminate remaining whitespaces such as empty lines and start parsing.
105 buf = trimWhitespaces(buf);
106
107 uint_fast64_t state = 0;
108 uint_fast64_t lastState = (uint_fast64_t)-1;
109 uint_fast64_t const startIndexComparison = lastState;
110 cnt = 0;
111
112 // Now parse the assignments of labels to nodes.
113 while (buf[0] != '\0') {
114 // Parse the state number and iterate over its labels (atomic propositions).
115 // Stop at the end of the line.
116 state = checked_strtol(buf, &buf);
117
118 // If the state has already been read or skipped once there might be a problem with the file (doubled lines, or blocks).
119 STORM_LOG_THROW(state > lastState || lastState == startIndexComparison, storm::exceptions::WrongFormatException,
120 "Error while parsing " << filename << ": State " << state << " was found but has already been read or skipped previously.");
121
122 while ((buf[0] != '\r') && (buf[0] != '\n') && (buf[0] != '\0')) {
123 cnt = skipWord(buf) - buf;
124 if (cnt == 0) {
125 // The next character is a separator.
126 // If it is a line separator, we continue with next node.
127 // Otherwise, we skip it and try again.
128 if (buf[0] == '\n' || buf[0] == '\r') {
129 break;
130 }
131 buf++;
132 } else {
133 // Copy the label to the buffer, null terminate it and add it to labeling.
134 strncpy(proposition, buf, cnt);
135 proposition[cnt] = '\0';
136
137 // Has the label been declared in the header?
138 STORM_LOG_THROW(labeling.containsLabel(proposition), storm::exceptions::WrongFormatException,
139 "Error while parsing " << filename << ": Atomic proposition" << proposition << " was found but not declared.");
140 labeling.addLabelToState(proposition, state);
141 buf += cnt;
142 }
143 }
144 buf = trimWhitespaces(buf);
145 lastState = state;
146 }
147
148 return labeling;
149}
150
151} // namespace parser
152} // namespace storm
void addLabel(std::string const &label)
Adds a new label to the labelings.
bool containsLabel(std::string const &label) const
Checks whether a label is registered within this labeling.
This class manages the labeling of the state space with a number of (atomic) labels.
void addLabelToState(std::string const &label, storm::storage::sparse::state_type state)
Adds a label to a given state.
static storm::models::sparse::StateLabeling parseAtomicPropositionLabeling(uint_fast64_t stateCount, std::string const &filename)
Reads a label file and puts the result in an AtomicPropositionsLabeling object.
Opens a file and maps it to memory providing a char* containing the file content.
Definition MappedFile.h:21
char const * getData() const
Returns a pointer to the beginning of the mapped file data.
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:28
Contains all file parsers and helper classes.
char const * skipWord(char const *buf)
Skips all numbers, letters and special characters.
Definition cstring.cpp:49
uint_fast64_t checked_strtol(char const *str, char const **end)
Calls strtol() internally and checks if the new pointer is different from the original one,...
Definition cstring.cpp:21
char const * trimWhitespaces(char const *buf)
Skips spaces, tabs, newlines and carriage returns.
Definition cstring.cpp:62