/** *ReturnsaDFAcreatedfromtheNFA.
*/
DFA convert() { // create state 0, the "reject" state
getState(DFAState::Label({})); // create a state representing being in all of the NFA's start states at once
std::vector<int> startStates = fNFA.fStartStates;
std::sort(startStates.begin(), startStates.end()); // this becomes state 1, our start state
DFAState* start = getState(DFAState::Label(startStates)); this->scanState(start);
private: /** *Returnsanexistingstatewiththegivenlabel,orcreatesanewoneandreturnsit.
*/
DFAState* getState(DFAState::Label label) { auto found = fStates.find(label);
if (found == fStates.end()) {
int id = fStates.size();
fStates[label] = std::unique_ptr<DFAState>(new DFAState(id, label)); return fStates[label].get();
} return found->second.get();
}
void add(int nfaState, std::vector<int>* states) {
NFAState state = fNFA.fStates[nfaState];
if (state.fKind == NFAState::kRemapped_Kind) {
for (int next : state.fData) { this->add(next, states);
}
} else {
for (int entry : *states) {
if (nfaState == entry) { return;
}
}
states->push_back(nfaState);
}
}
void addTransition(char c, int start, int next) { while (fTransitions.size() <= (size_t) c) {
fTransitions.push_back(std::vector<int>());
}
std::vector<int>& row = fTransitions[c]; while (row.size() <= (size_t) start) {
row.push_back(INVALID);
}
row[start] = next;
}
void scanState(DFAState* state) {
state->fIsScanned = true;
for (char c = START_CHAR; c <= END_CHAR; ++c) {
std::vector<int> next;
int bestAccept = INT_MAX;
for (int idx : state->fLabel.fStates) { const NFAState& nfaState = fNFA.fStates[idx];
if (nfaState.accept(c)) {
for (int nextState : nfaState.fNext) {
if (fNFA.fStates[nextState].fKind == NFAState::kAccept_Kind) {
bestAccept = std::min(bestAccept, fNFA.fStates[nextState].fData[0]);
} this->add(nextState, &next);
}
}
}
std::sort(next.begin(), next.end());
DFAState* nextState = this->getState(DFAState::Label(next)); this->addTransition(c, state->fId, nextState->fId);
if (bestAccept != INT_MAX) { while (fAccepts.size() <= (size_t) nextState->fId) {
fAccepts.push_back(INVALID);
}
fAccepts[nextState->fId] = bestAccept;
}
if (!nextState->fIsScanned) { this->scanState(nextState);
}
}
}
// collapse rows with the same transitions to a single row. This is common, as each row // represents a character and often there are many characters for which all transitions are // identical (e.g. [0-9] are treated the same way by all lexer rules) void computeMappings() { // mappings[<input row>] = <output row>
std::vector<std::vector<int>*> uniques; // this could be done more efficiently, but O(n^2) is plenty fast for our purposes
for (size_t i = 0; i < fTransitions.size(); ++i) {
int found = -1;
for (size_t j = 0; j < uniques.size(); ++j) {
if (*uniques[j] == fTransitions[i]) {
found = j; break;
}
}
if (found == -1) {
found = (int) uniques.size();
uniques.push_back(&fTransitions[i]);
}
fCharMappings.push_back(found);
}
std::vector<std::vector<int>> newTransitions;
for (std::vector<int>* row : uniques) {
newTransitions.push_back(*row);
}
fTransitions = newTransitions;
}
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.1Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-08-26)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.