40 void reportError(
const _Token_& _token,
const QString& _errorMsg)
42 messages.reportError(_errorMsg, _token.line);
45 void reportUnexpected(
const _Token_& _token)
47 reportError(_token, clog_qt::qformat(
"Unexpected '{}'.", _token.toString()));
50 void reportUnexpected(
const _Token_& _token,
typename _Token_::Type _expectedType)
52 reportError(_token, clog_qt::qformat(
"Expected '{}' before '{}'.", _Token_::typeToString(_expectedType), _token.toString()));
55 bool isOfType(
const _Token_& _token,
typename _Token_::Type _type)
57 if(_token.type == _type)
return true;
58 reportUnexpected(_token, _type);
62 const _Token_& getNextToken()
64 if(backToken.isEmpty())
66 return (currentToken = lexer->nextToken());
68 return (currentToken = backToken.takeLast());
71 void pushBackToken(
const _Token_& _new_current)
73 backToken.append(currentToken);
74 currentToken = _new_current;
81 switch(currentToken.type)
83 case _Token_::CURIE_CONSTANT:
85 if(currentToken.curie.canResolve(&urlManager))
87 r = currentToken.curie.resolve(&urlManager);
91 reportError(currentToken, clog_qt::qformat(
"Unknown curie prefix '{}'", currentToken.curie.prefix()));
96 case _Token_::URI_CONSTANT:
97 r = urlManager.base().resolved(currentToken.string);
101 reportUnexpected(currentToken);
109 if(isOfType(currentToken, _Token_::UNDERSCORECOLON))
115 switch(currentToken.type)
117 case _Token_::IDENTIFIER:
118 label = currentToken.string;
125 case _Token_::INTEGER_CONSTANT:
126 case _Token_::FLOAT_CONSTANT:
127 label = currentToken.string;
129 if(currentToken.type == _Token_::IDENTIFIER)
131 label += currentToken.string;
136 reportUnexpected(currentToken);
139 if(blankNodes.contains(label))
141 return blankNodes.value(label);
144 blankNodes[label] = bn;
153 switch(currentToken.type)
155 case _Token_::STARTBOXBRACKET:
158 isOfType(currentToken, _Token_::ENDBOXBRACKET);
162 case _Token_::QUESTION:
166 if(currentToken.type != _Token_::IDENTIFIER and currentToken.type != _Token_::A)
168 reportUnexpected(currentToken);
170 QString name = currentToken.type == _Token_::IDENTIFIER ? currentToken.string :
"a";
172 return Subject(name, Subject::Type::Variable);
178 case _Token_::UNDERSCORECOLON:
179 return parseBlankNode();
187 switch(currentToken.type)
191 return knowCore::Uris::rdf::a;
199 switch(currentToken.type)
201 case _Token_::QUESTION:
205 if(currentToken.type != _Token_::IDENTIFIER and currentToken.type != _Token_::A)
207 reportUnexpected(currentToken);
209 QString name = currentToken.type == _Token_::IDENTIFIER ? currentToken.string :
"a";
211 appendTriple(_subject, _predicate,
Object(name, Object::Type::Variable));
215 reportUnexpected(currentToken);
219 case _Token_::UNDERSCORECOLON:
221 appendTriple(_subject, _predicate, parseBlankNode());
224 case _Token_::CURIE_CONSTANT:
225 case _Token_::URI_CONSTANT:
227 appendTriple(_subject, _predicate, parseIri());
230 case _Token_::STRING_CONSTANT:
232 QString str = currentToken.string;
235 if(currentToken.type == _Token_::CIRCUMFLEXCIRCUMFLEX)
238 literal_uri = parseIri();
240 switch(currentToken.type)
242 case _Token_::LANG_TAG:
244 appendTriple(_subject, _predicate, literal_uri, str, currentToken.string);
250 appendTriple(_subject, _predicate, literal_uri, str, QString());
257 appendTriple(_subject, _predicate, knowCore::Uris::xsd::boolean,
true);
261 appendTriple(_subject, _predicate, knowCore::Uris::xsd::boolean,
false);
264 case _Token_::INTEGER_CONSTANT:
265 appendTriple(_subject, _predicate, knowCore::Uris::xsd::integer, knowCore::BigNumber::fromString(currentToken.string).expectSuccess());
268 case _Token_::FLOAT_CONSTANT:
269 appendTriple(_subject, _predicate, knowCore::Uris::select(currentToken.string.indexOf(
'e') == -1, knowCore::Uris::xsd::decimal, knowCore::Uris::xsd::float64), knowCore::BigNumber::fromString(currentToken.string).expectSuccess());
272 case _Token_::STARTBOXBRACKET:
278 if(currentToken.type != _Token_::ENDBOXBRACKET)
280 parseSingleSubject(bn, _Token_::ENDBOXBRACKET);
281 appendTriple(_subject, _predicate, bn);
285 appendTriple(_subject, _predicate, bn);
291 case _Token_::STARTBRACKET:
295 if(currentToken.type == _Token_::ENDBRACKET)
297 appendTriple(_subject, _predicate, knowCore::Uris::rdf::nil);
304 appendTriple(_subject, _predicate, bn);
306 while(currentToken.type != _Token_::END_OF_FILE)
308 parseObject(bn, knowCore::Uris::rdf::first);
310 if(currentToken.type == _Token_::ENDBRACKET)
312 appendTriple(bn, knowCore::Uris::rdf::rest, knowCore::Uris::rdf::nil);
318 appendTriple(bn, knowCore::Uris::rdf::rest, nbn);
326 case _Token_::LOAD_FILE:
329 if(not isOfType(currentToken, _Token_::STARTBRACKET))
return;
331 if(not isOfType(currentToken, _Token_::STRING_CONSTANT))
return;
332 QString filename = currentToken.string;
334 QUrl base = QUrl(urlManager.base());
335 QString base_fn = base.scheme() ==
"qrc" ?
":" + base.path() : base.toLocalFile();
336 QString fn = QFileInfo(base_fn).dir().absolutePath() +
"/" + filename;
338 if(f.open(QIODevice::ReadOnly))
340 appendTriple<QString>(_subject, _predicate, knowCore::Uris::xsd::string, QString::fromUtf8(f.readAll()), QString());
342 reportError(currentToken, clog_qt::qformat(
"Failed to open file '{}'", f.fileName()));
346 if(not isOfType(currentToken, _Token_::ENDBRACKET))
return;
351 reportUnexpected(currentToken);
356 void parseSingleSubject(
const Subject & subject,
const typename _Token_::Type & _endType)
358 while(currentToken.type != _Token_::END_OF_FILE)
362 while(currentToken.type != _Token_::END_OF_FILE)
364 parseObject(subject, predicate);
366 if(currentToken.type == _Token_::COMA)
375 if(currentToken.type == _endType)
380 else if(isOfType(currentToken, _Token_::SEMI))
383 if(currentToken.type == _endType)
391 using _Base_::appendTriple;
392 template<
typename _T_>
393 void appendTriple(
const Subject & _subject,
const knowCore::Uri & _predicate,
const knowCore::Uri& _dataTypeUri,
const _T_ & _value,
const QString& _lang = QString())
395 const auto [success, object, message] = Object::fromValue(_dataTypeUri, _value, _lang);
398 this->appendTriple(
Triple(_subject, _predicate,
object));
400 reportError(currentToken, clog_qt::qformat(
"Failed to create object for value '{}' with error '{}'", _value, message));
405 this->appendTriple(
Triple(_subject, _predicate, _value));
412 appendTriple(_subject, _predicate, lit);
414 reportError(currentToken, clog_qt::qformat(
"Failed to parse RDF literal '{}' of type '{}' with error '{}'", _value, _dataTypeUri, message));