|
1
2
3
4
5
6
7
8
9
10
|
/*
* File: simplefsa_impl.hpp
* Author: mlenart
*
* Created on November 4, 2013, 1:05 PM
*/
#ifndef SIMPLEFSA_IMPL_HPP
#define SIMPLEFSA_IMPL_HPP
|
|
11
12
|
#include <iostream>
|
|
13
14
|
#include "fsa.hpp"
|
|
15
|
//#pragma pack(push, 1) /* push current alignment to stack */
|
|
16
17
|
struct StateData {
|
|
18
19
|
unsigned char transitionsNum;
bool accepting;
|
|
20
21
|
};
|
|
22
|
//#pragma pack(pop) /* restore original alignment from stack */
|
|
23
24
|
template <class T>
|
|
25
26
|
SimpleFSA<T>::SimpleFSA(const unsigned char* ptr, const Deserializer<T>& deserializer, bool isTransducer)
: FSA<T>(ptr, deserializer), isTransducer(isTransducer) {
|
|
27
28
29
30
31
32
33
|
}
template <class T>
SimpleFSA<T>::~SimpleFSA() {
}
|
|
34
|
static inline unsigned int decodeOffset(const unsigned char* ptr) {
|
|
35
36
37
38
39
|
unsigned int res = 0;
res = ptr[0] << 16 | ptr[1] << 8 | ptr[2];
return res;
}
|
|
40
41
42
43
44
45
46
47
48
|
static inline StateData decodeStateData(const unsigned char* ptr) {
static const unsigned char acceptingFlag = 128;
static const unsigned char transitionsNumMask = 127;
StateData res;
res.transitionsNum = (*ptr) & transitionsNumMask;
res.accepting = (*ptr) & acceptingFlag;
return res;
}
|
|
49
50
51
|
template <class T>
void SimpleFSA<T>::proceedToNext(const char c, State<T>& state) const {
const unsigned char* fromPointer = this->initialStatePtr + state.getOffset();
|
|
52
|
long transitionsTableOffset = 1;
|
|
53
54
55
|
if (state.isAccepting()) {
transitionsTableOffset += state.getValueSize();
}
|
|
56
|
StateData stateData = decodeStateData(fromPointer);
|
|
57
58
|
const unsigned char* foundTransition = fromPointer + transitionsTableOffset;
bool found = false;
|
|
59
60
|
unsigned int increment = this->isTransducer ? 5 : 4;
for (unsigned int i = 0; i < stateData.transitionsNum; i++, foundTransition += increment) {
|
|
61
62
63
64
65
66
67
68
|
if ((char) *foundTransition == c) {
found = true;
break;
}
}
// const_cast<Counter*>(&counter)->increment(foundTransition - transitionsStart + 1);
if (!found) {
state.setNextAsSink();
|
|
69
70
|
}
else {
|
|
71
72
|
unsigned int offset = decodeOffset(foundTransition + 1);
const unsigned char* nextStatePointer = this->initialStatePtr + offset;
|
|
73
74
|
StateData nextStateData = decodeStateData(nextStatePointer);
if (nextStateData.accepting) {
|
|
75
|
T object;
|
|
76
|
long size = this->deserializer.deserialize(nextStatePointer + 1, object);
|
|
77
|
state.setNext(offset, object, size);
|
|
78
79
|
}
else {
|
|
80
81
|
state.setNext(offset);
}
|
|
82
83
84
|
if (isTransducer) {
state.setLastTransitionValue(*(foundTransition + 4));
}
|
|
85
86
87
88
89
|
}
}
#endif /* SIMPLEFSA_IMPL_HPP */
|