LIMA
Libre Multilingual Analyzer — C++ API
Loading...
Searching...
No Matches
SpiritTokenizerLoader.cpp
Go to the documentation of this file.
1// Copyright 2002-2013 CEA LIST
2// SPDX-FileCopyrightText: 2022 CEA LIST <gael.de-chalendar@cea.fr>
3//
4// SPDX-License-Identifier: MIT
5
8
9#include "State.h"
10#include "Transition.h"
11#include "Condition.h"
12
13#include <fstream>
14
15namespace Lima
16{
17namespace LinguisticProcessing
18{
19namespace FlatTokenizer
20{
21
22SpiritTokenizerLoader::SpiritTokenizerLoader(Automaton& automaton, const std::string& fileName) :
23 m_automaton(automaton)
24{
26 namespace qi = boost::spirit::qi;
27 namespace ascii = boost::spirit::ascii;
28 using ascii::space;
29 typedef std::string::const_iterator iterator_type;
31
32 tokenizer tokenizer_parser; // Our grammar
33
34 std::string str;
35 std::ifstream file(fileName.c_str(), std::ifstream::binary);
36 if( ! file.is_open() ){
37 std::string error_message = std::string("cannot open file ") + fileName;
38 LERROR << error_message;
39 throw std::runtime_error(error_message);
40 }
41
43
44 std::string::const_iterator iter = str.begin();
45 std::string::const_iterator end = str.end();
46
48 bool r = phrase_parse(iter, end, tokenizer_parser, skipper, tokenizer_automaton);
49
50 if (r && iter == end)
51 {
52 LDEBUG << "Parsing " << fileName << " succeeded: "<<tokenizer_automaton.size()<<" states";
53 std::vector<tokenizer_state>::const_iterator it, itBegin, itEnd;
54 itBegin = tokenizer_automaton.begin();
55 it = tokenizer_automaton.begin(); itEnd = tokenizer_automaton.end();
56 for (; it != itEnd; it++)
57 {
58 const tokenizer_state& state = *it;
59 LDEBUG << "Loading state " << state.id;
60 State* newState = stateNamed(Common::Misc::utf8stdstring2limastring(state.id));
61 std::vector<tokenizer_transition>::const_iterator tit, titEnd;
62 tit = state.transitions.begin(); titEnd = state.transitions.end();
63 for (; tit != titEnd; tit++)
64 {
65 // create transition
66 const tokenizer_transition& transition = *tit;
67 LDEBUG << " Loading transition to " << transition.target << " (" << stateNamed(Common::Misc::utf8stdstring2limastring(transition.target)) << ") type=" << transition.transition;
68 Transition* newTransition = new Transition(newState);
69 LDEBUG << " transition is " << newTransition;
70 // setting target set
71 newTransition->setToState(stateNamed(Common::Misc::utf8stdstring2limastring(transition.target)));
72 // setting events
73 std::vector<std::string>::const_iterator eventIt, eventItEnd;
74 eventIt = transition.event.begin(); eventItEnd = transition.event.end();
75 for (; eventIt!= eventItEnd; eventIt++)
76 {
77 LDEBUG << " Adding event " << *eventIt;
78 newTransition->events().push_back(m_automaton.charChart()->classNamed(Common::Misc::utf8stdstring2limastring(*eventIt)));
79 }
80 // setting preconditions
81 std::vector<tokenizer_precondition>::const_iterator preconditionsIt, preconditionsItEnd;
82 preconditionsIt = transition.preconditions.begin(); preconditionsItEnd = transition.preconditions.end();
83 for (; preconditionsIt != preconditionsItEnd; preconditionsIt++)
84 {
85 LDEBUG << " Adding precondition";
86 newTransition->conditions().before().push_back(Events(m_automaton.charChart()));
87 const tokenizer_precondition& precondition = *preconditionsIt;
88 tokenizer_precondition::const_iterator preIt, preItEnd;
89 preIt = precondition.begin(); preItEnd = precondition.end();
90 for (; preIt != preItEnd; preIt++)
91 {
92 LDEBUG << " " << *preIt;
93 newTransition->conditions().before().back().addEventNamed(Common::Misc::utf8stdstring2limastring(*preIt));
94 }
95 }
96 // setting postconditions
97 std::vector<tokenizer_postcondition>::const_iterator postconditionsIt, postconditionsItEnd;
98 postconditionsIt = transition.postconditions.begin(); postconditionsItEnd = transition.postconditions.end();
99 for (; postconditionsIt != postconditionsItEnd; postconditionsIt++)
100 {
101 LDEBUG << " Adding postcondition";
102 newTransition->conditions().after().push_back(Events(m_automaton.charChart()));
103 const tokenizer_postcondition& postcondition = *postconditionsIt;
104 tokenizer_postcondition::const_iterator postIt, postItEnd;
105 postIt = postcondition.begin(); postItEnd = postcondition.end();
106 for (; postIt != postItEnd; postIt++)
107 {
108 LDEBUG << " " << *postIt << " ; postconditions size: " << newTransition->conditions().after().size();
109 newTransition->conditions().after().back().addEventNamed(Common::Misc::utf8stdstring2limastring(*postIt));
110 }
111 }
112 // setting parameters
113 newTransition->setFlush(transition.transition == FLUSH);
114 LDEBUG << " setTokenize: " << (transition.transition == TOKEN);
115 newTransition->setTokenize(transition.transition == TOKEN);
116 // setting statuses
117 std::vector<std::string>::const_iterator statusesIt, statusesItEnd;
118 statusesIt = transition.statuses.begin(); statusesItEnd = transition.statuses.end();
119 for (; statusesIt != statusesItEnd; statusesIt++)
120 {
121 if (!newTransition->setSetting(Common::Misc::utf8stdstring2limastring(*statusesIt)))
122 {
123 LERROR << "Unknown status setting: " << *statusesIt;
124 }
125 }
126 // store transition
127 newState->transitions().push_back(newTransition);
128 }
129 if (it == itBegin)
130 {
131 m_automaton.setStartState(newState);
132 }
133 }
134 }
135 else
136 {
137 LERROR << "Parsing of tokenizer file failed: " << fileName;
138 }
139}
140
141State* SpiritTokenizerLoader::stateNamed(const LimaString& name)
142{
143 State* newState = m_automaton.stateNamed(name);
144 if (newState == nullptr)
145 {
146 newState = new State(name, m_automaton);
147 m_automaton.states().push_back(newState);
148 }
149 return newState;
150}
151
152}
153}
154}
#define LDEBUG
Definition LimaCommon.h:157
#define LERROR
Definition LimaCommon.h:161
#define TOKENIZERLOADERLOGINIT
#define skipper
std::vector< std::string > tokenizer_postcondition
std::vector< std::string > tokenizer_precondition
std::vector< tokenizer_state > tokenizer_automaton
const std::shared_ptr< CharChart > charChart() const
Definition Automaton.h:61
const State * stateNamed(const LimaString &name) const
const std::vector< State * > & states() const
Definition Automaton.h:55
const std::vector< Events > & before() const
Definition Condition.h:43
const std::vector< Events > & after() const
Definition Condition.h:46
SpiritTokenizerLoader(Automaton &automaton, const std::string &fileName)
std::list< Transition * > & transitions()
Definition State.h:48
void readStream(std::istream &is, std::string &dest)
Read an input stream into a string, until EOF.
LimaString utf8stdstring2limastring(const std::string &src)
NAUTITIA.
QString LimaString
Definition LimaString.h:33
std::vector< tokenizer_transition > transitions
std::vector< tokenizer_postcondition > postconditions
std::vector< tokenizer_precondition > preconditions
std::vector< std::string > event
std::vector< std::string > statuses