Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
inflection/tools/dictionary-parser/bin/*
fst/__pycache__/*
build/*
.vscode/launch.json
.vscode/settings.json
fst/__pycache__/*
inflection/tools/dictionary-parser/bin/*
2,167 changes: 1,113 additions & 1,054 deletions inflection/resources/org/unicode/inflection/dictionary/dictionary_sr.lst

Large diffs are not rendered by default.

1,916 changes: 1,121 additions & 795 deletions inflection/resources/org/unicode/inflection/dictionary/inflectional_sr.xml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ namespace inflection::grammar::synthesis {
SrGrammarSynthesizer_SrDisplayFunction::SrGrammarSynthesizer_SrDisplayFunction(const ::inflection::dialog::SemanticFeatureModel& model)
: super()
, dictionary(*npc(::inflection::dictionary::DictionaryMetaData::createDictionary(::inflection::util::LocaleUtils::SERBIAN())))
, countFeature(model.getFeature(GrammemeConstants::NUMBER))
, genderFeature(model.getFeature(GrammemeConstants::GENDER))
, partOfSpeechFeature(model.getFeature(GrammemeConstants::POS))
, caseFeature(*npc(model.getFeature(GrammemeConstants::CASE)))
, numberFeature(*npc(model.getFeature(GrammemeConstants::NUMBER)))
, genderFeature(*npc(model.getFeature(GrammemeConstants::GENDER)))
, inflector(::inflection::dictionary::Inflector::getInflector(::inflection::util::LocaleUtils::SERBIAN()))
, tokenizer(::inflection::tokenizer::TokenizerFactory::createTokenizer(::inflection::util::LocaleUtils::SERBIAN()))
, dictionaryInflector(::inflection::util::LocaleUtils::SERBIAN(),{
{GrammemeConstants::POS_NOUN(), GrammemeConstants::POS_ADJECTIVE(), GrammemeConstants::POS_VERB()},
{GrammemeConstants::PERSON_THIRD(), GrammemeConstants::PERSON_FIRST(), GrammemeConstants::PERSON_SECOND()},
{GrammemeConstants::POS_NOUN(), GrammemeConstants::POS_ADJECTIVE()},
{GrammemeConstants::NUMBER_SINGULAR(), GrammemeConstants::NUMBER_PLURAL()},
{GrammemeConstants::GENDER_MASCULINE(), GrammemeConstants::GENDER_FEMININE(), GrammemeConstants::GENDER_NEUTER()}
}, {}, true)
Expand All @@ -42,23 +42,54 @@ SrGrammarSynthesizer_SrDisplayFunction::~SrGrammarSynthesizer_SrDisplayFunction(
{
}

::inflection::dialog::DisplayValue * SrGrammarSynthesizer_SrDisplayFunction::getDisplayValue(const dialog::SemanticFeatureModel_DisplayData &displayData, const ::std::map<::inflection::dialog::SemanticFeature, ::std::u16string> &constraints, bool enableInflectionGuess) const
::std::u16string SrGrammarSynthesizer_SrDisplayFunction::inflectString(const ::std::map<::inflection::dialog::SemanticFeature, ::std::u16string>& constraints, const ::std::u16string& lemma) const
{
const auto displayValue = GrammarSynthesizerUtil::getTheBestDisplayValue(displayData, constraints);
if (displayValue == nullptr) {
return nullptr;
::std::u16string countString(GrammarSynthesizerUtil::getFeatureValue(constraints, numberFeature));
::std::u16string caseString(GrammarSynthesizerUtil::getFeatureValue(constraints, caseFeature));
auto genderString = GrammarSynthesizerUtil::getFeatureValue(constraints, genderFeature);

::std::u16string inflection;

// The nominative/caseless is unmarked in the patterns so we need to do something like this
::std::vector<::std::u16string> string_constraints;
if (!countString.empty()) {
string_constraints.emplace_back(countString);
}
::std::u16string displayString = displayValue->getDisplayString();
if (displayString.empty()) {
return nullptr;
if (!caseString.empty() && caseString != GrammemeConstants::CASE_NOMINATIVE()) {
string_constraints.emplace_back(caseString);
}
if (!genderString.empty()) {
string_constraints.emplace_back(genderString);
}
// The nominative/caseless is unmarked in the patterns, so we need to do something like this
int64_t wordGrammemes = 0;
dictionary.getCombinedBinaryType(&wordGrammemes, lemma);

// To make compiler quiet about unused variable.
if (enableInflectionGuess)
return nullptr;
auto inflectionResult = dictionaryInflector.inflect(lemma, wordGrammemes, string_constraints, {});
if (inflectionResult) {
inflection = *inflectionResult;
}

if (inflection.empty()) {
return lemma;
}

return inflection;
}

// TODO Implement the rest
return nullptr;
::inflection::dialog::DisplayValue * SrGrammarSynthesizer_SrDisplayFunction::getDisplayValue(const dialog::SemanticFeatureModel_DisplayData &displayData, const ::std::map<::inflection::dialog::SemanticFeature, ::std::u16string> &constraints, bool /* enableInflectionGuess */) const
{
::std::u16string displayString;
if (!displayData.getValues().empty()) {
displayString = displayData.getValues()[0].getDisplayString();
}
if (displayString.empty()) {
return nullptr;
}
if (dictionary.isKnownWord(displayString)) {
displayString = inflectString(constraints, displayString);
}
return new ::inflection::dialog::DisplayValue(displayString, constraints);
}

} // namespace inflection::grammar::synthesis
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,22 @@ class inflection::grammar::synthesis::SrGrammarSynthesizer_SrDisplayFunction
public:
typedef ::inflection::dialog::DefaultDisplayFunction super;

private:
const ::inflection::dictionary::DictionaryMetaData& dictionary;
const ::inflection::dialog::SemanticFeature* countFeature { };
const ::inflection::dialog::SemanticFeature* genderFeature { };
const ::inflection::dialog::SemanticFeature* partOfSpeechFeature { };
const ::std::unique_ptr<::inflection::tokenizer::Tokenizer> tokenizer;
const ::inflection::dialog::DictionaryLookupInflector dictionaryInflector;

public:
::inflection::dialog::DisplayValue * getDisplayValue(const dialog::SemanticFeatureModel_DisplayData &displayData, const ::std::map<::inflection::dialog::SemanticFeature, ::std::u16string> &constraints, bool enableInflectionGuess) const override;

public:
explicit SrGrammarSynthesizer_SrDisplayFunction(const ::inflection::dialog::SemanticFeatureModel& model);
~SrGrammarSynthesizer_SrDisplayFunction() override;

public:
SrGrammarSynthesizer_SrDisplayFunction(SrGrammarSynthesizer_SrDisplayFunction&) = delete;
SrGrammarSynthesizer_SrDisplayFunction& operator=(const SrGrammarSynthesizer_SrDisplayFunction&) = delete;

private:
::std::u16string inflectString(const ::std::map<::inflection::dialog::SemanticFeature, ::std::u16string>& constraints, const ::std::u16string& lemma) const;

const ::inflection::dictionary::DictionaryMetaData& dictionary;
const ::inflection::dialog::SemanticFeature& caseFeature;
const ::inflection::dialog::SemanticFeature& numberFeature;
const ::inflection::dialog::SemanticFeature& genderFeature;
const ::inflection::dictionary::Inflector &inflector;
const ::std::unique_ptr<::inflection::tokenizer::Tokenizer> tokenizer;
::inflection::dialog::DictionaryLookupInflector dictionaryInflector;
};
11 changes: 10 additions & 1 deletion inflection/test/resources/inflection/dialog/inflection/sr.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,18 @@
License & terms of use: http://www.unicode.org/copyright.html
-->
<inflectionTest locale="sr">
<!-- Some nominative case tests where we don't expect changes -->
<!-- Tests of dictionary words -->
<test><source case="nominative" number="singular">једро</source><result>једро</result></test>
<test><source case="nominative" number="plural">једро</source><result>једра</result></test>
<test><source case="nominative" number="singular">жена</source><result>жена</result></test>
<test><source case="nominative" number="singular">камен</source><result>камен</result></test>
<test><source case="nominative" pos="proper-noun">Петар</source><result>Петар</result></test>
<test><source case="vocative" number="singular" gender="feminine" pos="proper-noun">Љубица</source><result>Љубице</result></test>
<test><source case="vocative" number="singular" gender="feminine" pos="noun">Србија</source><result>Србијо</result></test>
<test><source case="instrumental" number="plural" gender="masculine" pos="noun">становник</source><result>становницима</result></test>
<test><source case="genitive" number="plural" gender="neuter" pos="adjective">плава</source><result>плавe</result></test>
<!-- Words not in the dictionary but similar in shape -->
<!-- test><source case="vocative" number="singular" gender="masculine" pos="noun">уранак</source><result>уранче</result></test -->
<!-- test><source case="vocative" number="singular" gender="masculine" pos="noun">игроказ</source><result>игрокаже</result></test -->
<!-- test><source case="vocative" number="singular" gender="masculine" pos="noun">пашњак</source><result>пашњаче</result></test -->
</inflectionTest>