Blame view

morfeusz/fsa/simplefsa_impl.hpp 2.39 KB
Michał Lenart authored
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
Michał Lenart authored
11
12
#include <iostream>
Michał Lenart authored
13
14
#include "fsa.hpp"
Michał Lenart authored
15
//#pragma pack(push, 1)  /* push current alignment to stack */
Michał Lenart authored
16
Michał Lenart authored
17
18
namespace morfeusz {
Michał Lenart authored
19
struct StateData {
Michał Lenart authored
20
21
    unsigned char transitionsNum;
    bool accepting;
Michał Lenart authored
22
23
};
Michał Lenart authored
24
//#pragma pack(pop)   /* restore original alignment from stack */
Michał Lenart authored
25
26

template <class T>
Michał Lenart authored
27
28
SimpleFSA<T>::SimpleFSA(const unsigned char* ptr, const Deserializer<T>& deserializer, bool isTransducer)
: FSA<T>(ptr, deserializer), isTransducer(isTransducer) {
Michał Lenart authored
29
30
31
32
33
34
35
}

template <class T>
SimpleFSA<T>::~SimpleFSA() {

}
Michał Lenart authored
36
static inline unsigned int decodeOffset(const unsigned char* ptr) {
Michał Lenart authored
37
38
39
40
41
    unsigned int res = 0;
    res = ptr[0] << 16 | ptr[1] << 8 | ptr[2];
    return res;
}
Michał Lenart authored
42
43
44
45
46
47
48
49
50
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;
}
Michał Lenart authored
51
52
53
template <class T>
void SimpleFSA<T>::proceedToNext(const char c, State<T>& state) const {
    const unsigned char* fromPointer = this->initialStatePtr + state.getOffset();
Michał Lenart authored
54
    long transitionsTableOffset = 1;
Michał Lenart authored
55
56
57
    if (state.isAccepting()) {
        transitionsTableOffset += state.getValueSize();
    }
Michał Lenart authored
58
    StateData stateData = decodeStateData(fromPointer);
Michał Lenart authored
59
60
    const unsigned char* foundTransition = fromPointer + transitionsTableOffset;
    bool found = false;
Michał Lenart authored
61
62
    unsigned int increment = this->isTransducer ? 5 : 4;
    for (unsigned int i = 0; i < stateData.transitionsNum; i++, foundTransition += increment) {
Michał Lenart authored
63
64
65
66
67
68
69
        if ((char) *foundTransition == c) {
            found = true;
            break;
        }
    }
    if (!found) {
        state.setNextAsSink();
Michał Lenart authored
70
71
    }
    else {
Michał Lenart authored
72
73
        unsigned int offset = decodeOffset(foundTransition + 1);
        const unsigned char* nextStatePointer = this->initialStatePtr + offset;
Michał Lenart authored
74
75
        StateData nextStateData = decodeStateData(nextStatePointer);
        if (nextStateData.accepting) {
Michał Lenart authored
76
            T object;
Michał Lenart authored
77
            long size = this->deserializer.deserialize(nextStatePointer + 1, object);
Michał Lenart authored
78
            state.setNext(offset, object, size);
Michał Lenart authored
79
80
        }
        else {
Michał Lenart authored
81
82
83
84
85
            state.setNext(offset);
        }
    }
}
Michał Lenart authored
86
87
}
Michał Lenart authored
88
89
#endif	/* SIMPLEFSA_IMPL_HPP */