source: src/lem_utf8/lemfst.cpp

Last change on this file was 5f4d9c3, checked in by Maciej Prill <mprill@…>, 13 years ago

Rewritten the build system, added lem UTF-8 version.

  • Property mode set to 100644
File size: 3.8 KB
Line 
1#include "lemfst.h"
2
3LemFST::LemFST(const char* plik_fst)
4{
5    fst = StdFst::Read(plik_fst);
6}
7
8
9LemFST::~LemFST(void)
10{
11        delete fst;
12        path.clear();
13}
14
15/** Zwraca true jezeli s jest koncowym */
16bool LemFST::accept(State s) {
17        if (s == fst::kNoStateId) return false;
18        return fst->Final(s)!=StdFst::Weight::Zero();
19}
20
21
22LemFST::State LemFST::start() { 
23        return fst->Start();
24}
25
26
27/** Przechodzi do nastepnego stanu po jednym znaku */
28LemFST::State LemFST::next(State s, Char c) {
29        if (s==fst::kNoStateId) return fst::kNoStateId;
30        ArcsIt aiter(*fst, s);
31        for (; !aiter.Done(); aiter.Next()) {
32                StdArc arc = aiter.Value();     
33                if (arc.ilabel==c) return arc.nextstate;
34               
35        }
36        return fst::kNoStateId;
37}
38
39/** Konsumuje slowo W zaczynajac w stanie s.
40  * Zwraca:
41  * State (int64) -  w jakim sie znajdzie
42  * kNoStateId (-1) - gdy nie moze dokonac takiego przejscia.
43  */
44LemFST::State LemFST::next(State s, Word w) {
45        if (s==fst::kNoStateId) return fst::kNoStateId;
46        LemFST::WordIt it;
47        State ns = s;
48        for(it=w.begin(); it!=w.end(); ++it) {
49                ns = next(ns, *it);
50                if (ns==fst::kNoStateId) {
51                        return fst::kNoStateId;
52                }
53        }
54        return ns;
55
56}
57
58/** Funkcja zwraca kolejne sciezki z automatu w formie generatora.
59  * Ustawienie s na kNoStateId (lub -1) restartuje generator.
60  * Dopoki s!=-1 metoda zwraca przy kolejnych wywolaniach kolejne sciezki od stanu s
61  * do stanow konczacych.
62  * Sciezke mozna odzyskac poprzez metode getPath();
63  */
64long LemFST::cont(State s, Word *result, int maxPath) {
65        // Restart generatora po podaniu -1
66        // Lub przekroczeniu dlugosci sciezki
67        if (s==fst::kNoStateId || path.size() > maxPath) {
68                path.clear();
69                return 0;
70        }
71
72
73        // Stos jest pusty. Mozemy dodac do niego wierzcholek poczatkowy.
74        if (path.empty()) {
75                path.push_back(getStateInfo(s, fst::kNoStateId, 0));
76        }
77        while(!path.empty()) {
78
79                // Zdejmujemy ze stosu stan i jego iterator:
80                StateInfo *state = &path.back();
81                ArcsIt *ait = state->it;
82
83                // Jezeli stan jest koncowy to zwracamy sciezke do stanu "s"
84                // Dodatkowo sprawdzamy czy juz nie startowalismy z tego stanu, aby nie wyswietlac wielokrotnie tego samego
85                if (!state->checked && accept(state->id)) {
86                        state->checked = true;
87                        StateInfo tState;
88                        PathRevIt pit=path.rbegin();
89                        State prevId = pit->id;
90                        result->clear();
91                        for(; pit!=path.rend(); ++pit) {
92                                tState = (*pit);
93                                if (tState.id == prevId && tState.prev!=fst::kNoStateId && tState.id !=s) {
94                                        ArcsIt *tArcIt = tState.it;
95                                        result->push_front(tState.symbol);
96                                }
97                                if (tState.prev==fst::kNoStateId) break;
98                                prevId = tState.prev;           
99                        }
100                        ait->Next();
101                        return path.size();
102                }
103
104
105                // Skonczylismy sprawdzac dany iterator (stan).
106                // Dlatego mozemy go usunac ze stosu.
107                if (ait->Done()) {
108                        path.pop_back();
109                        // Jezeli jakies wierzcholki sa jeszcze na stosie to kontynuuj:
110                        if (path.size() > 0) continue;
111                        // w.p.p zakoncz.
112                        else return 0;
113                }
114
115
116                // Odwiedzamy stan.
117                // Dodajemy jego nastepnikow:
118                for(; !ait->Done(); ait->Next()) {
119                        State next = ait->Value().nextstate;
120                        Char isymbol = ait->Value().ilabel;
121                        path.push_back(getStateInfo(next, state->id, isymbol));
122                }
123        } // Koniec (while(!path.empty())
124
125
126
127        return 0;
128}
129
130
131/** Zwraca strukture StateInfo uzupelniajac ja o dane
132  * Parametry:
133  * s - ktory stan opisujemy
134  * prev - poprzednik stanu w automacie
135  * isymbol - symbol po jakim dostalismy sie z 'prev' do 's'
136  */
137inline const LemFST::StateInfo LemFST::getStateInfo(State s, State prev, Char isymbol) {
138        StateInfo sInfo;
139        sInfo.id = s; 
140        sInfo.it = new ArcsIt(*fst, s); //Wyciagamy iterator z automatu
141        sInfo.symbol = isymbol; 
142        sInfo.prev = prev;
143        sInfo.checked = false; // Czy stan byl juz sprawdzany jako koncowy
144        return sInfo;
145}
146
147
Note: See TracBrowser for help on using the repository browser.