LIMA
Libre Multilingual Analyzer — C++ API
Loading...
Searching...
No Matches
XmlSyntagmaticMatrixFileHandler.cpp
Go to the documentation of this file.
1// Copyright 2002-2020 CEA LIST
2// SPDX-FileCopyrightText: 2022 CEA LIST <gael.de-chalendar@cea.fr>
3//
4// SPDX-License-Identifier: MIT
5
17// ---------------------------------------------------------------------------
18// Includes
19// ---------------------------------------------------------------------------
23
25
26
27#include<boost/tokenizer.hpp>
28
29#include <sstream>
30#include <iostream>
31
32using namespace std;
33
34using namespace Lima::Common::Misc;
35using namespace Lima::Common::MediaticData;
37
38namespace Lima {
39namespace LinguisticProcessing {
40namespace SyntacticAnalysis {
41
42// ---------------------------------------------------------------------------
43// XMLSyntagmaticMatrixFileHandler: Constructors and Destructor
44// ---------------------------------------------------------------------------
46 m_matrices(matrices),
47 m_currentChainType(NO_CHAIN_TYPE),
48 m_language(language)
49{
50}
51
55
56
57// ---------------------------------------------------------------------------
58// XMLSyntagmaticMatrixFileHandler: Overrides of the SAX ErrorHandler interface
59// ---------------------------------------------------------------------------
60bool XMLSyntagmaticMatrixFileHandler::error(const QXmlParseException& e)
61{
63 LERROR << "Error at file " << e.systemId()
64 << ", line " << e.lineNumber()
65 << ", char " << e.columnNumber()
66 << " Message: " << e.message();
67 return false;
68}
69
70bool XMLSyntagmaticMatrixFileHandler::fatalError(const QXmlParseException& e)
71{
73 LERROR << "Fatal Error at file " << e.systemId()
74 << ", line " << e.lineNumber()
75 << ", char " << e.columnNumber()
76 << " Message: " << e.message();
77 return false;
78}
79
80bool XMLSyntagmaticMatrixFileHandler::warning(const QXmlParseException& e)
81{
83 LWARN << "Warning at file " << e.systemId()
84 << ", line " << e.lineNumber()
85 << ", char " << e.columnNumber()
86 << " Message: " << e.message();
87 return true;
88}
89
90
91// ---------------------------------------------------------------------------
92// XMLSyntagmaticMatrixFileHandler: Overrides of the SAX DTDHandler interface
93// ---------------------------------------------------------------------------
94// ---------------------------------------------------------------------------
95// XMLSyntagmaticMatrixFileHandler: Overrides of the SAX DocumentHandler interface
96// ---------------------------------------------------------------------------
98{
99 std::string str = limastring2utf8stdstring(chars);
100
101 if (m_currentElement == "nom")
102 {
103// <!ELEMENT nom (#PCDATA ) >
104 m_currentFilterName = str;
105// std::cerr << "Current filter name is: " << m_currentFilterName << std::endl;
106 }
107 else if (m_currentElement == "attribut")
108 {
109// <!ELEMENT attribut (#PCDATA ) >
110
111 //string2wstring(attribute, str);
112 m_currentFilterAttributes.insert(Common::MediaticData::MediaticData::changeable().stringsPool(m_language)[chars]);
113// std::wcerr << L"Current attribute is: " << attribute << std::endl;
114 }
115 else if (m_currentElement == "categorie")
116 {
117// <!ELEMENT categorie (#PCDATA ) >
118
119 LinguisticCode filterCategory;
120 if ( isdigit(str[0]))
121 {
122 filterCategory = LinguisticCode::fromString(str);
123 }
124 else
125 {
126 filterCategory = static_cast<const Common::MediaticData::LanguageData&>(MediaticData::single().mediaData(m_matrices.language())).getPropertyCodeManager().getPropertyManager("MICRO").getPropertyValue(str);
127 }
128 m_currentFilterCategories.insert(filterCategory);
129// std::cerr << "Current category is: " << filterCategory << std::endl;
130 }
131 return true;
132}
133
134
135bool XMLSyntagmaticMatrixFileHandler::startElement(const QString & namespaceURI, const QString & name, const QString & qName, const QXmlAttributes & attributes)
136{
137 LIMA_UNUSED(namespaceURI);
138 LIMA_UNUSED(qName);
139 // <!ELEMENT matrice_précedence (chaine+, matrice+)>
140
141 if (name == 0)
142 {
143 SALOGINIT;
144 LERROR << "Error: receiving a null element name while parsing matrix file";
145 return false;
146 }
147
148 const QString& stringName = name;
149
150// std::cerr << "Starting element: " << stringName << std::endl;
151
152 if (stringName == ("matrice"))
153// <!ELEMENT matrice (ligne+, debuts+, fin+)>
154// <!ATTLIST matrice type (nominale | verbale) #REQUIRED>
155 {
156 QString currentMatrixType = attributes.value("type");
157 if (currentMatrixType == "nominale") m_currentMatrixType = NOMINAL;
158 else if (currentMatrixType == "verbale") m_currentMatrixType = VERBAL;
159 else m_currentMatrixType = NO_CHAIN_TYPE;
160 }
161 else if (stringName == ("ligne"))
162// <!ELEMENT ligne (succ*)>
163// <!ATTLIST ligne REF IDREF #IMPLIED>
164 {
165 m_currentMatrixLineId = attributes.value("REF").toUtf8().data();
166 }
167 else if (stringName == ("succ"))
168// <!ELEMENT succ EMPTY>
169// <!ATTLIST succ REF IDREFS #IMPLIED>
170 {
171// std::cerr << "Creating new succ for " << m_currentMatrixLineId << " (" << m_currentMatrixType << ")" << std::endl;
172 using namespace boost;
173 std::string successorsStr = (attributes.value("REF")).toUtf8().data();
174 std::set< std::string > successors;
175
176 tokenizer<> tok(successorsStr);
177 copy(tok.begin(), tok.end(),
178 std::insert_iterator< std::set< std::string > >(successors, successors.end()));
179
181 std::set< std::string >::iterator it = successors.begin();
182 for (; it != successors.end(); it++)
183 {
184// std::cerr << "Inserting " << (*it) << " / " << *(m_tokenFilters[m_currentMatrixType][(*it)]) << " in row " << std::endl;
185 row.m_filters.insert(m_tokenFilters[m_currentMatrixType][(*it)]);
186 }
187// std::cerr << "New row is " << row << std::endl;
188 TokenFilter filter = m_tokenFilters[m_currentMatrixType][m_currentMatrixLineId];
189// std::cerr << "Filter is " << filter << std::endl;
190 if (m_currentMatrixType == NOMINAL)
191 m_matrices.nominal().filters().insert(std::make_pair(filter, row));
192 else if (m_currentMatrixType == VERBAL)
193 m_matrices.verbal().filters().insert(std::make_pair(filter, row));
194 }
195 else if (stringName == ("debuts"))
196// <!ELEMENT debuts EMPTY>
197// <!ATTLIST debuts REF IDREFS #IMPLIED>
198 {
199// std::cerr << "Creating new debuts" << std::endl;
200 using namespace boost;
201 std::string beginningsStr = (attributes.value("REF")).toUtf8().data();
202 std::set< std::string > beginnings;
203
204 tokenizer<> tok(beginningsStr);
205 copy(tok.begin(), tok.end(),
206 std::insert_iterator< std::set< std::string > >(beginnings, beginnings.end()));
207
209 std::set< std::string >::iterator it = beginnings.begin();
210 for (; it != beginnings.end(); it++)
211 {
212 row.m_filters.insert(m_tokenFilters[m_currentMatrixType][(*it)]);
213 }
214 if (m_currentMatrixType == NOMINAL)
215 {
216 m_matrices.nominalBegin() = row;
217// std::cerr << "New debuts is " << m_matrices.nominalBegin() << std::endl;
218 }
219 else if (m_currentMatrixType == VERBAL)
220 {
221 m_matrices.verbalBegin() = row;
222// std::cerr << "New debuts is " << m_matrices.verbalBegin() << std::endl;
223 }
224 }
225 else if (stringName == ("fins"))
226// <!ELEMENT fins EMPTY>
227// <!ATTLIST fins REF IDREFS #IMPLIED>
228 {
229// std::cerr << "Creating new fins" << std::endl;
230 using namespace boost;
231 std::string endingsStr = (attributes.value("REF")).toUtf8().data();
232 std::set< std::string > endings;
233
234 tokenizer<> tok(endingsStr);
235 copy(tok.begin(), tok.end(),
236 std::insert_iterator< std::set< std::string > >(endings, endings.end()));
237
239 std::set< std::string >::iterator it = endings.begin();
240 for (; it != endings.end(); it++)
241 {
242 row.m_filters.insert(m_tokenFilters[m_currentMatrixType][(*it)]);
243 }
244// std::cerr << "New fins is " << row << std::endl;
245 if (m_currentMatrixType == NOMINAL)
246 m_matrices.nominalEnd() = row;
247 else if (m_currentMatrixType == VERBAL)
248 m_matrices.verbalEnd() = row;
249 }
250 else if (stringName == ("chaine"))
251// <!ELEMENT chaine (filtre+) >
252// <!ATTLIST chaine type (nominale | verbale) #REQUIRED>
253 {
254 std::string currentChainType = (attributes.value("type")).toUtf8().data();
255 if (currentChainType == "nominale") m_currentChainType = NOMINAL;
256 else if (currentChainType == "verbale") m_currentChainType = VERBAL;
257 else m_currentChainType = NO_CHAIN_TYPE;
258// std::cerr << m_currentChainType << std::endl;
259 }
260 else if (stringName == ("filtre"))
261// <!ELEMENT filtre ( nom, attribut*, categorie+)>
262// <!ATTLIST filtre ID ID #REQUIRED>
263 {
264 m_currentFilterId = (attributes.value("ID")).toUtf8().data();
265 m_currentFilterAttributes =std::set< StringsPoolIndex >();
266 m_currentFilterCategories = std::set< LinguisticCode >();
267// std::cerr << m_currentFilterId << std::endl;
268 }
269 else if ( (stringName == ("nom")) || (stringName == ("attribut"))
270 || (stringName == ("categorie")) )
271 {
272// <!ELEMENT nom (#PCDATA ) >
273 m_currentElement = stringName.toUtf8().data();
274// std::cerr << "Current element is: " << m_currentElement << std::endl;
275 }
276 return true;
277}
278
279bool XMLSyntagmaticMatrixFileHandler::endElement(const QString & namespaceURI, const QString & name, const QString & qName)
280{
281 LIMA_UNUSED(namespaceURI);
282 LIMA_UNUSED(qName);
283 if (name == 0)
284 {
285 SALOGINIT;
286 LERROR << "Error: receiving a null closing element name while parsing matrix file";
287 return false;
288 }
289 const QString& stringName = name;
290// std::cerr << "Finishing element: " << stringName << std::endl;
291 // set the current module name and create its entry if necessary
292 if ( stringName == ("matrice") )
293 {
294 m_currentMatrixType = NO_CHAIN_TYPE;
295 }
296 else if ( stringName == ("chaine") )
297 {
298 m_currentChainType = NO_CHAIN_TYPE;
299 }
300 else if (stringName == ("filtre"))
301// <!ELEMENT filtre ( nom, attribut*, categorie+)>
302// <!ATTLIST filtre ID ID #REQUIRED>
303 {
304 TokenFilter filter(m_currentFilterId, m_currentFilterName, m_currentFilterAttributes, m_currentFilterCategories);
305// std::cerr << "New Filter is: " << *filter << std::endl;
306 m_tokenFilters[m_currentChainType][m_currentFilterId] = filter;
307 m_currentFilterId = "";
308 m_currentFilterName = "";
309 m_currentFilterAttributes = std::set< StringsPoolIndex >();
310 m_currentFilterCategories = std::set< LinguisticCode >();
311 }
312 else if ( (stringName == ("nom")) || (stringName == ("attribut"))
313 || (stringName == ("categorie")) )
314 {
315// <!ELEMENT nom (#PCDATA ) >
316 m_currentElement = "";
317// std::cerr << "Current element is: " << m_currentElement << std::endl;
318 }
319 else if ( stringName == ("chaine") )
320 {
321 m_currentMatrixLineId = "";
322 }
323 return true;
324
325}
326
327
328} // closing namespace SyntacticAnalysis
329} // closing namespace LinguisticProcessing
330} // closing namespace Lima
#define LWARN
Definition LimaCommon.h:160
#define LIMA_UNUSED(x)
Definition LimaCommon.h:224
#define LERROR
Definition LimaCommon.h:161
#define SALOGINIT
Holds linguistic data for one language.
static LinguisticCode fromString(const std::string &str)
Definition StdBitset.h:89
bool startElement(const QString &namespaceURI, const QString &name, const QString &qName, const QXmlAttributes &attributes) override
bool endElement(const QString &namespaceURI, const QString &name, const QString &qName) override
static MediaticData & changeable()
singleton accessor
Definition Singleton.h:71
std::string limastring2utf8stdstring(const Lima::LimaString &phrase, uint32_t size0)
Convert a wide string to a string , in dest up to size bytes.
NAUTITIA.
STL namespace.