Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
NFA::Machine Struct Reference

#include <NFA.h>

Public Member Functions

 Machine ()
 
 ~Machine ()
 
 Machine (Machine &&inMachine)
 
void operator= (Machine &&inMachine)
 
 Machine (Builder *inBuilder)
 
StateIndex feed (const char *&nextChar) const
 
std::string dumpDFAGraphViz () const
 

Detailed Description

Definition at line 37 of file NFA.h.

Constructor & Destructor Documentation

◆ Machine() [1/3]

NFA::Machine::Machine ( )
inline

Definition at line 39 of file NFA.h.

39: stateAndOffsetToNextStateMap(nullptr), numClasses(0), numStates(0) {}

◆ ~Machine()

NFA::Machine::~Machine ( )

Definition at line 379 of file NFA.cpp.

380 {
381 if(stateAndOffsetToNextStateMap)
382 {
383 delete [] stateAndOffsetToNextStateMap;
384 stateAndOffsetToNextStateMap = nullptr;
385 }
386 }

◆ Machine() [2/3]

NFA::Machine::Machine ( Machine && inMachine)
inline

Definition at line 42 of file NFA.h.

42{ moveFrom(std::move(inMachine)); }

◆ Machine() [3/3]

NFA::Machine::Machine ( Builder * inBuilder)

Definition at line 319 of file NFA.cpp.

320 {
321 // Convert the NFA constructed by the builder to a DFA.
322 std::vector<DFAState> dfaStates = convertToDFA(builder);
323 WAVM_ASSERT_THROW(dfaStates.size() <= internalMaxStates);
324 delete builder;
325
326 Timing::Timer timer;
327
328 // Transpose the [state][character] transition map to [character][state].
329 std::vector<StateTransitionsByChar> stateTransitionsByChar;
330 for(Uptr charIndex = 0;charIndex < 256;++charIndex)
331 {
332 stateTransitionsByChar.push_back(StateTransitionsByChar((U8)charIndex,dfaStates.size()));
333 stateTransitionsByChar[charIndex].nextStateByInitialState = new StateIndex[dfaStates.size()];
334 for(Uptr stateIndex = 0;stateIndex < dfaStates.size();++stateIndex)
335 { stateTransitionsByChar[charIndex].nextStateByInitialState[stateIndex] = dfaStates[stateIndex].nextStateByChar[charIndex]; }
336 }
337
338 // Sort the [character][state] transition map by the [state] column.
339 numStates = dfaStates.size();
340 std::sort(stateTransitionsByChar.begin(),stateTransitionsByChar.end());
341
342 // Build a minimal set of character equivalence classes that have the same transition across all states.
343 U8 characterToClassMap[256];
344 U8 representativeCharsByClass[256];
345 numClasses = 1;
346 characterToClassMap[stateTransitionsByChar[0].c] = 0;
347 representativeCharsByClass[0] = stateTransitionsByChar[0].c;
348 for(Uptr charIndex = 1;charIndex < stateTransitionsByChar.size();++charIndex)
349 {
350 if(stateTransitionsByChar[charIndex] != stateTransitionsByChar[charIndex-1])
351 {
352 representativeCharsByClass[numClasses] = stateTransitionsByChar[charIndex].c;
353 ++numClasses;
354 }
355 characterToClassMap[stateTransitionsByChar[charIndex].c] = U8(numClasses - 1);
356 }
357
358 // Build a [charClass][state] transition map.
359 stateAndOffsetToNextStateMap = new InternalStateIndex[numClasses * numStates];
360 for(Uptr classIndex = 0;classIndex < numClasses;++classIndex)
361 {
362 for(Uptr stateIndex = 0;stateIndex < numStates;++stateIndex)
363 {
364 stateAndOffsetToNextStateMap[stateIndex + classIndex * numStates] = InternalStateIndex(dfaStates[stateIndex].nextStateByChar[representativeCharsByClass[classIndex]]);
365 }
366 }
367
368 // Build a map from character index to offset into [charClass][initialState] transition map.
369 WAVM_ASSERT_THROW((numClasses - 1) * (numStates - 1) <= UINT32_MAX);
370 for(Uptr charIndex = 0;charIndex < 256;++charIndex)
371 {
372 charToOffsetMap[charIndex] = U32(numStates * characterToClassMap[charIndex]);
373 }
374
375 Timing::logTimer("reduced DFA character classes",timer);
376 Log::printf(Log::Category::metrics," reduced DFA character classes to %u\n",numClasses);
377 }
uint32_t U32
Definition BasicTypes.h:9
uint8_t U8
Definition BasicTypes.h:5
PointerIntHelper< sizeof(size_t)>::UnsignedIntType Uptr
Definition BasicTypes.h:22
#define WAVM_ASSERT_THROW(cond)
Definition Errors.h:29
LOGGING_API void printf(Category category, const char *format,...)
Definition Logging.cpp:30
std::vector< DFAState > convertToDFA(Builder *builder)
Definition NFA.cpp:90
I16 StateIndex
Definition NFA.h:14
void logTimer(const char *context, Timer &timer)
Definition Timing.h:28
#define UINT32_MAX
Definition stdint.h:188
Here is the call graph for this function:

Member Function Documentation

◆ dumpDFAGraphViz()

std::string NFA::Machine::dumpDFAGraphViz ( ) const

Definition at line 510 of file NFA.cpp.

511 {
512 std::string result;
513 result += "digraph {\n";
514 std::set<StateIndex> terminalStates;
515
516 CharSet* classCharSets = (CharSet*)alloca(sizeof(CharSet) * numClasses);
517 memset(classCharSets,0,sizeof(CharSet) * numClasses);
518 for(Uptr charIndex = 0;charIndex < 256;++charIndex)
519 {
520 const Uptr classIndex = charToOffsetMap[charIndex] / numStates;
521 classCharSets[classIndex].add((U8)charIndex);
522 }
523
524 {
525 std::map<StateIndex,CharSet> transitions;
526 for(Uptr classIndex = 0;classIndex < numClasses;++classIndex)
527 {
528 const InternalStateIndex nextState = stateAndOffsetToNextStateMap[0 + classIndex * numStates];
529 CharSet& transitionPredicate = transitions[nextState];
530 transitionPredicate = classCharSets[classIndex] | transitionPredicate;
531 }
532
533 Uptr startIndex = 0;
534 for(auto transitionPair : transitions)
535 {
536 if((transitionPair.first & ~edgeDoesntConsumeInputFlag) != unmatchedCharacterTerminal)
537 {
538 result += "start" + std::to_string(startIndex) + "[shape=triangle label=\"\"];\n";
539
540 std::string edgeLabel = getGraphEdgeLabel(transitionPair.second);
541 std::string nextStateName = transitionPair.first < 0
542 ? "terminal" + std::to_string(-(transitionPair.first & ~edgeDoesntConsumeInputFlag))
543 : "state" + std::to_string(transitionPair.first);
544 result += "start" + std::to_string(startIndex)
545 + " -> "
546 + nextStateName + "[label=\""
547 + (transitionPair.first < 0 && (transitionPair.first & edgeDoesntConsumeInputFlag) != 0 ? "&epsilon; " : "")
548 + escapeString(edgeLabel) + "\"];\n";
549
550 if(transitionPair.first < 0)
551 {
552 terminalStates.emplace(StateIndex(transitionPair.first & ~edgeDoesntConsumeInputFlag));
553 }
554
555 ++startIndex;
556 }
557 }
558 }
559
560 for(Uptr stateIndex = 1;stateIndex < numStates;++stateIndex)
561 {
562 result += "state" + std::to_string(stateIndex) + "[shape=square label=\"" + std::to_string(stateIndex) + "\"];\n";
563
564 std::map<StateIndex,CharSet> transitions;
565 for(Uptr classIndex = 0;classIndex < numClasses;++classIndex)
566 {
567 const InternalStateIndex nextState = stateAndOffsetToNextStateMap[stateIndex + classIndex * numStates];
568 CharSet& transitionPredicate = transitions[nextState];
569 transitionPredicate = classCharSets[classIndex] | transitionPredicate;
570 }
571
572 for(auto transitionPair : transitions)
573 {
574 if((transitionPair.first & ~edgeDoesntConsumeInputFlag) != unmatchedCharacterTerminal)
575 {
576 std::string edgeLabel = getGraphEdgeLabel(transitionPair.second);
577 std::string nextStateName = transitionPair.first < 0
578 ? "terminal" + std::to_string(-(transitionPair.first & ~edgeDoesntConsumeInputFlag))
579 : "state" + std::to_string(transitionPair.first);
580 result += "state" + std::to_string(stateIndex)
581 + " -> "
582 + nextStateName + "[label=\""
583 + (transitionPair.first < 0 && (transitionPair.first & edgeDoesntConsumeInputFlag) != 0 ? "&epsilon; " : "")
584 + escapeString(edgeLabel) + "\"];\n";
585
586 if(transitionPair.first < 0)
587 {
588 terminalStates.emplace(transitionPair.first);
589 }
590 }
591 }
592 }
593 for(auto terminalState : terminalStates)
594 {
595 result += "terminal" + std::to_string(-(terminalState & ~edgeDoesntConsumeInputFlag))
596 + "[shape=octagon label=\"" + std::to_string(maximumTerminalStateIndex - (terminalState & ~edgeDoesntConsumeInputFlag)) + "\"];\n";
597 }
598 result += "}\n";
599 return result;
600 }
std::string getGraphEdgeLabel(const CharSet &charSet)
Definition NFA.cpp:436
DenseStaticIntSet< U8, 256 > CharSet
Definition NFA.h:11
std::string escapeString(const std::string &string)
Definition NFA.cpp:399
@ maximumTerminalStateIndex
Definition NFA.h:20
@ edgeDoesntConsumeInputFlag
Definition NFA.h:18
@ unmatchedCharacterTerminal
Definition NFA.h:19
Definition name.hpp:106
memset(pInfo->slotDescription, ' ', 64)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ feed()

StateIndex NFA::Machine::feed ( const char *& nextChar) const
inline

Definition at line 51 of file NFA.h.

52 {
53 Iptr state = 0;
54 do
55 {
56 state = stateAndOffsetToNextStateMap[state + charToOffsetMap[(U8)nextChar[0]]];
57 if(state < 0) { nextChar += 1; break; }
58 state = stateAndOffsetToNextStateMap[state + charToOffsetMap[(U8)nextChar[1]]];
59 if(state < 0) { nextChar += 2; break; }
60 state = stateAndOffsetToNextStateMap[state + charToOffsetMap[(U8)nextChar[2]]];
61 if(state < 0) { nextChar += 3; break; }
62 state = stateAndOffsetToNextStateMap[state + charToOffsetMap[(U8)nextChar[3]]];
63 nextChar += 4;
64 }
65 while(state >= 0);
67 {
68 --nextChar;
69 state &= ~edgeDoesntConsumeInputFlag;
70 }
71 return (StateIndex)state;
72 }
PointerIntHelper< sizeof(size_t)>::IntType Iptr
Definition BasicTypes.h:23
Here is the caller graph for this function:

◆ operator=()

void NFA::Machine::operator= ( Machine && inMachine)
inline

Definition at line 43 of file NFA.h.

43{ moveFrom(std::move(inMachine)); }

The documentation for this struct was generated from the following files: