41 void reportError(
const _Token_& _token,
const QString& _errorMsg)
43 messages.reportError(_errorMsg, _token.line);
46 void reportUnexpected(
const _Token_& _token)
48 reportError(_token, clog_qt::qformat(
"Unexpected '{}'.", _token.toString()));
51 void reportUnexpected(
const _Token_& _token,
typename _Token_::Type _expectedType)
54 clog_qt::qformat(
"Expected '{}' before '{}'.",
55 _Token_::typeToString(_expectedType), _token.toString()));
58 bool isOfType(
const _Token_& _token,
typename _Token_::Type _type)
60 if(_token.type == _type)
62 reportUnexpected(_token, _type);
66 const _Token_& getNextToken()
68 if(backToken.isEmpty())
70 return (currentToken = lexer->nextToken());
74 return (currentToken = backToken.takeLast());
77 void pushBackToken(
const _Token_& _new_current)
79 backToken.append(currentToken);
80 currentToken = _new_current;
86 switch(currentToken.type)
88 case _Token_::CURIE_CONSTANT:
90 if(currentToken.curie.canResolve(&urlManager))
92 r = currentToken.curie.resolve(&urlManager);
96 reportError(currentToken,
97 clog_qt::qformat(
"Unknown curie prefix '{}'", currentToken.curie.prefix()));
102 case _Token_::URI_CONSTANT:
103 r = urlManager.base().resolved(currentToken.string);
107 reportUnexpected(currentToken);
115 if(isOfType(currentToken, _Token_::UNDERSCORECOLON))
121 switch(currentToken.type)
123 case _Token_::IDENTIFIER:
124 label = currentToken.string;
131 case _Token_::INTEGER_CONSTANT:
132 case _Token_::FLOAT_CONSTANT:
133 label = currentToken.string;
135 if(currentToken.type == _Token_::IDENTIFIER)
137 label += currentToken.string;
142 reportUnexpected(currentToken);
145 if(blankNodes.contains(label))
147 return blankNodes.value(label);
152 blankNodes[label] = bn;
161 switch(currentToken.type)
163 case _Token_::STARTBOXBRACKET:
166 isOfType(currentToken, _Token_::ENDBOXBRACKET);
170 case _Token_::QUESTION:
174 if(currentToken.type != _Token_::IDENTIFIER and currentToken.type != _Token_::A)
176 reportUnexpected(currentToken);
178 QString name = currentToken.type == _Token_::IDENTIFIER ? currentToken.string :
"a";
180 return Subject(name, Subject::Type::Variable);
186 case _Token_::UNDERSCORECOLON:
187 return parseBlankNode();
195 switch(currentToken.type)
199 return knowCore::Uris::rdf::a;
207 switch(currentToken.type)
209 case _Token_::QUESTION:
213 if(currentToken.type != _Token_::IDENTIFIER and currentToken.type != _Token_::A)
215 reportUnexpected(currentToken);
217 QString name = currentToken.type == _Token_::IDENTIFIER ? currentToken.string :
"a";
219 appendTriple(_subject, _predicate,
Object(name, Object::Type::Variable));
223 reportUnexpected(currentToken);
227 case _Token_::UNDERSCORECOLON:
229 appendTriple(_subject, _predicate, parseBlankNode());
232 case _Token_::CURIE_CONSTANT:
233 case _Token_::URI_CONSTANT:
235 appendTriple(_subject, _predicate, parseIri());
238 case _Token_::STRING_CONSTANT:
240 QString str = currentToken.string;
243 if(currentToken.type == _Token_::CIRCUMFLEXCIRCUMFLEX)
246 literal_uri = parseIri();
248 switch(currentToken.type)
250 case _Token_::LANG_TAG:
252 appendTriple(_subject, _predicate, literal_uri, str, currentToken.string);
258 appendTriple(_subject, _predicate, literal_uri, str, QString());
265 appendTriple(_subject, _predicate, knowCore::Uris::xsd::boolean,
true);
269 appendTriple(_subject, _predicate, knowCore::Uris::xsd::boolean,
false);
272 case _Token_::INTEGER_CONSTANT:
273 appendTriple(_subject, _predicate, knowCore::Uris::xsd::integer,
274 knowCore::BigNumber::fromString(currentToken.string).expect_success());
277 case _Token_::FLOAT_CONSTANT:
278 appendTriple(_subject, _predicate,
279 knowCore::Uris::select(currentToken.string.indexOf(
'e') == -1,
280 knowCore::Uris::xsd::decimal,
281 knowCore::Uris::xsd::float64),
282 knowCore::BigNumber::fromString(currentToken.string).expect_success());
285 case _Token_::STARTBOXBRACKET:
291 if(currentToken.type != _Token_::ENDBOXBRACKET)
293 parseSingleSubject(bn, _Token_::ENDBOXBRACKET);
294 appendTriple(_subject, _predicate, bn);
298 appendTriple(_subject, _predicate, bn);
304 case _Token_::STARTBRACKET:
308 if(currentToken.type == _Token_::ENDBRACKET)
310 appendTriple(_subject, _predicate, knowCore::Uris::rdf::nil);
317 appendTriple(_subject, _predicate, bn);
319 while(currentToken.type != _Token_::END_OF_FILE)
321 parseObject(bn, knowCore::Uris::rdf::first);
323 if(currentToken.type == _Token_::ENDBRACKET)
325 appendTriple(bn, knowCore::Uris::rdf::rest, knowCore::Uris::rdf::nil);
331 appendTriple(bn, knowCore::Uris::rdf::rest, nbn);
339 case _Token_::LOAD_FILE:
342 if(not isOfType(currentToken, _Token_::STARTBRACKET))
345 if(not isOfType(currentToken, _Token_::STRING_CONSTANT))
347 QString filename = currentToken.string;
349 QUrl base = QUrl(urlManager.base());
350 QString base_fn = base.scheme() ==
"qrc" ?
":" + base.path() : base.toLocalFile();
351 QString fn = QFileInfo(base_fn).dir().absolutePath() +
"/" + filename;
353 if(f.open(QIODevice::ReadOnly))
355 appendTriple<QString>(_subject, _predicate, knowCore::Uris::xsd::string,
356 QString::fromUtf8(f.readAll()), QString());
360 reportError(currentToken, clog_qt::qformat(
"Failed to open file '{}'", f.fileName()));
364 if(not isOfType(currentToken, _Token_::ENDBRACKET))
370 reportUnexpected(currentToken);
375 void parseSingleSubject(
const Subject& subject,
const typename _Token_::Type& _endType)
377 while(currentToken.type != _Token_::END_OF_FILE)
381 while(currentToken.type != _Token_::END_OF_FILE)
383 parseObject(subject, predicate);
385 if(currentToken.type == _Token_::COMA)
394 if(currentToken.type == _endType)
399 else if(isOfType(currentToken, _Token_::SEMI))
402 if(currentToken.type == _endType)
410 using _Base_::appendTriple;
411 template<
typename _T_>
414 const QString& _lang = QString())
416 const auto [success, object, message] = Object::fromValue(_dataTypeUri, _value, _lang);
419 this->appendTriple(
Triple(_subject, _predicate,
object.value()));
423 reportError(currentToken,
424 clog_qt::qformat(
"Failed to create object for value '{}' with error '{}'",
425 _value, message.value()));
431 this->appendTriple(
Triple(_subject, _predicate, _value));
435 const QString& _lang)
440 appendTriple(_subject, _predicate, lit.value());
446 clog_qt::qformat(
"Failed to parse RDF literal '{}' of type '{}' with error '{}'",
447 _value, _dataTypeUri, message.value()));