Библиотека Падеж для Линукс - Access Violation
Модератор: Модераторы
Библиотека Падеж для Линукс - Access Violation
Есть такая библиотека склонения по падежам Покаташкина Г.Л., Плахова С.В. Не могу победить линукс-версию библиотеки (64-бит). При вызове so-функции возникает Access Violation. Что я делаю не так? Версия библиотеки 4.5 Unicode.
Ссылка на пример - https://cloud.mail.ru/public/o1fQ/BKVzUVxQQ
Ссылка на пример - https://cloud.mail.ru/public/o1fQ/BKVzUVxQQ
- Снег Север
- долгожитель
- Сообщения: 3067
- Зарегистрирован: 27.11.2007 15:14:47
- Контактная информация:
Эта библиотека когда-то писалась под делфи. У меня и там не работала. Могу только дать ссылку на королевство Делфи, вдруг поможет: http://www.delphikingdom.com/asp/viewit ... alogid=412
Спасибо за ответ. В курсе этой ссылки. К сожалению, ничего полезного для себя не нашел.
Добавлено спустя 1 час 19 минут 52 секунды:
Вопрос решился. У меня была какая-то косячная версия библиотеки. Обновил и все заработало.
Добавлено спустя 51 минуту 32 секунды:
Э-эх. Все равно часть функций не работает
.
Добавлено спустя 1 час 19 минут 52 секунды:
Вопрос решился. У меня была какая-то косячная версия библиотеки. Обновил и все заработало.
Добавлено спустя 51 минуту 32 секунды:
Э-эх. Все равно часть функций не работает
Не знаю. Я одному из разработчиков написал. Тишина.
Они исходники при покупке отдают.Alexander писал(а):Разработчику надо написать вначале, чтобы он её освободил под GNU/*GPL и только потом использовать.
Добавлено спустя 6 часов 14 минут 11 секунд:
Решил поделиться своей библиотекой.
https://github.com/WAYFARER87/NameCasePas
В свое время накидал на коленке и использовал 1 раз для обработки большого набора данных. Особо не тестировалась, но работает. Библиотека использует набор правил от небезызвестной ruby библиотеки Petrovich (https://github.com/petrovich/petrovich-rules)
Лицензия MIT, полностью кроссплатформенная. В репозитарии так же пример использования. Кроме склонения ФИО по падежам умеет определять пол.
Если кому то нужно, то я нормально оформлю репозитарий и создам страничку на форуме.
- Alexander
- энтузиаст
- Сообщения: 864
- Зарегистрирован: 18.12.2005 18:10:00
- Откуда: оттуда
- Контактная информация:
Вот это другое дело. С примером и работает. Поставил ей звезду на github'е .Решил поделиться своей библиотекой.
https://github.com/WAYFARER87/NameCasePas
Имхо, лишняя сторонняя приблуда = лишняя головная боль при дальнейшей поддержке проекта. Для "Падежа" в дельфях это проявилось, когда проект перелез с доюникодных версий на юникодные D2009+. Хорошо, тогда обошлось явным указанием всех типов string--> ansistring и pchar-->pansichar.
Впоследствии выпилил эту библиотеку из проекта и вздохнул с облегчением
Впоследствии выпилил эту библиотеку из проекта и вздохнул с облегчением
Жаль, что нет склонения должностей, подразделений, числительных, чисел прописью. В Падеже все это есть.WAYFARER писал(а):Решил поделиться своей библиотекой.
https://github.com/WAYFARER87/NameCasePas
Добавлено спустя 42 секунды:
А чем вы заменили?zoltanleo писал(а):Впоследствии выпилил эту библиотеку из проекта и вздохнул с облегчением
Зато есть октрытый код. Добавить недолго правила, не думаю что список должностей и подразделений будет большой. А что касается чисел прописью, то я бы ради такой мелочи не стал тащить стороннюю библиотеку в программе, можно за пять минут функцию накидать или нагуглить готовую.7bit писал(а):Жаль, что нет склонения должностей, подразделений, числительных, чисел прописью. В Падеже все это есть.
Юрия не правильно склоняетWAYFARER писал(а):Они исходники при покупке отдают.Alexander писал(а):Разработчику надо написать вначале, чтобы он её освободил под GNU/*GPL и только потом использовать.
Добавлено спустя 6 часов 14 минут 11 секунд:
Решил поделиться своей библиотекой.
https://github.com/WAYFARER87/NameCasePas
В свое время накидал на коленке и использовал 1 раз для обработки большого набора данных. Особо не тестировалась, но работает. Библиотека использует набор правил от небезызвестной ruby библиотеки Petrovich (https://github.com/petrovich/petrovich-rules)
Лицензия MIT, полностью кроссплатформенная. В репозитарии так же пример использования. Кроме склонения ФИО по падежам умеет определять пол.
Если кому то нужно, то я нормально оформлю репозитарий и создам страничку на форуме.
Код: Выделить всё
Юрийя
Юрийю
Юрийя
Юрийем
ЮрийеЕще и разные файлы в основном коде и в папке с примером
Добавлено спустя 3 часа 31 минуту 14 секунд:
Короче есть пара ошибок и, что самое главное, применение к utf8 строкам функции length как будто она должна вернуть количество символов в строке, а она возвращает количество байт, естественно.
Для корректной работы, нужно переписать либо с utf8Length (и будет зависеть библиотека от LCL_Base) либо конвертировать все в UTF16 и держать в уме, что каждый символ в 4 байта, либо написать свою реализацию UTF8Lenght.
Я подправил, так чтобы оно работало, НО логику надо менять, тк. поиск в суффиксах идет последовательно, то, например для имени Юрий - подбирает суффикс "й", вместо "ий", и по этому не верно склоняет в предложном падеже.
код поправленной библиотеки:
Код: Выделить всё
{The MIT License (MIT)
Copyright (c) 2024 Anton Lindeberg
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.}
unit NameCasePas;
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, fpjson, jsonparser, StrUtils, Dialogs;
type
{ TNameCase }
TNameCase = class
private
middlename, firstname, lastname, gender: string;
rules: TJSONData;
function inflect(Name: string; aCase: integer; ruleType: string): string;
function findInRules(Name: string; aCase: integer; ruleType: string): string;
function applyRule(Mods, Name: string; aCase: integer): string;
public
constructor Create;
function GetFirstName(AFirstName: string; ACase: integer): string;
function GetLastName(ALastName: string; ACase: integer): string;
function GetMiddleName(AMiddleName: string; ACase: integer): string;
function GetGender:String;
end;
const
CASE_DATIVE = 0; //родительный
const
CASE_GENITIVE = 1; //дательный
const
CASE_ACCUSATIVE = 2; //винительный
const
CASE_INSTRUMENTAL = 3; //творительный
const
CASE_PREPOSITIONAL = 4; //предложный
implementation
uses jsonscanner;
{ TCaseName }
constructor TNameCase.Create;
var
JSONParser: TJSONParser;
begin
JSONParser := TJSONParser.Create(TFileStream.Create(ExtractFilePath(ParamStr(0)) +
'rules.js', fmOpenRead), [TJSONOption.joUTF8]);
rules := JSONParser.Parse;
end;
function TNameCase.GetFirstName(AFirstName: string; ACase: integer): string;
begin
{ $this->firstname = $firstname;
return $this->inflect($this->firstname,$case,__FUNCTION__); }
self.firstname := AFirstName;
Result := inflect(firstname, ACase, 'firstname');
end;
function TNameCase.GetLastName(ALastName: string; ACase: integer): string;
begin
self.lastname := ALastName;
Result := inflect(lastname, ACase, 'lastname');
end;
function TNameCase.GetMiddleName(AMiddleName: string; ACase: integer): string;
begin
self.middlename := AMiddleName;
Result := inflect(middlename, ACase, 'middlename');
end;
function TNameCase.GetGender: String;
begin
Result:=gender;
end;
function CountChar(const str: string; const chr: char): integer;
var
i: integer;
begin
Result := 0;
for i := 1 to Length(str) do
if str[i] = chr then
Inc(Result);
end;
{ private function inflect($name,$case,$type) {
//если двойное имя или фамилия или отчество
if(substr_count($name,'-') > 0) {
$names_arr = explode('-',$name);
$result = '';
foreach($names_arr as $arr_name) {
$result .= $this->findInRules($arr_name,$case,$type).'-';
}
return substr($result,0,strlen($result)-1);
} else {
return $this->findInRules($name,$case,$type);
}
}}
function TNameCase.inflect(Name: string; aCase: integer; ruleType: string): string;
var
nameArr: TStringList;
i: integer;
res: string;
begin
if CountChar(Name, '-') > 0 then
begin
nameArr := TStringList.Create;
try
nameArr.DelimitedText := Name;
res := '';
for i := 0 to nameArr.Count - 1 do
res := res + findInRules(nameArr[i], aCase, ruleType) + '-';
Result := Copy(res, 1, Length(res) - 1);
finally
nameArr.Free;
end;
end
else
Result := findInRules(Name, aCase, ruleType);
end;
{ foreach($this->rules[$type]->suffixes as $rule) {
foreach($rule->test as $last_char) {
$last_name_char = substr($name,strlen($name)-strlen($last_char),strlen($last_char));
if($last_char == $last_name_char) {
if($rule->mods[$case] == '.')
continue;
if($this->gender == 'androgynous' || $this->gender == null)
$this->gender = $rule->gender;
return $this->applyRule($rule->mods,$name,$case);
}
}
}}
function TNameCase.findInRules(Name: string; aCase: integer; ruleType: string): string;
var
i, j: integer;
suffixes: TJSONData;
last_char: TJSONData;
last_name_char, rule: string;
begin
suffixes := rules.FindPath(ruleType).FindPath('suffixes');
for i := 0 to suffixes.Count - 1 do
begin
//last_name_char = substr($name,strlen($name)-strlen($last_char),strlen($last_char));
last_char := suffixes.Items[i].FindPath('test');
for j := 0 to last_char.Count - 1 do
begin
last_name_char := Copy(Name, Length(Name) - Length(last_char.Items[j].Value) +
1, Length(last_char.Items[j].Value));
if (last_char.Items[j].Value = last_name_char) then
begin
if suffixes.Items[i].FindPath('mods').Items[aCase].Value = '.' then Continue;
gender := suffixes.Items[i].FindPath('gender').Value;
Result := applyRule(suffixes.Items[i].FindPath(
'mods').Items[aCase].Value, Name, aCase);
end;
end;
end;
end;
//function substr_count(const substr: string; Str: string): integer;
function substr_count(Str: string; const substr: string): integer; //!!!
begin
if (Length(substr) = 0) or (Length(Str) = 0) or (Pos(substr, Str) = 0) then
Result := 0
else
//Result := (Length(Str) - Length(StringReplace(Str, substr, '', [rfReplaceAll]))) div
// Length(substr); // тут окажемся только когда в суффиксе есть "-" и какая-то буква. Length(substr) всегда = 1, нет смысла на него делить
Result:= str.CountChar('-') * 2; //будет работать только для кириллицы, за каждый символ "-" мы должны удалиить из имени по 2 байта
end;
function TNameCase.applyRule(Mods, Name: string; aCase: integer): string;
var
res: string;
begin
res := Copy(Name, 1, Length(Name) - substr_count(Mods, '-'));
res := res + StringReplace(Mods, '-', '', [rfReplaceAll]);
Result := res;
end;
end.- Alexander
- энтузиаст
- Сообщения: 864
- Зарегистрирован: 18.12.2005 18:10:00
- Откуда: оттуда
- Контактная информация:
> код поправленной библиотеки:
Юрий теперь в порядке, но похоже проблема и с именем Ольга. Видимо и другие имена и фамилии тоже.
Также не совсем понятно как быть с файлом rules.js - он привязан к расположению экзешника, что не совсем unix way. Или сделать расположение настраиваемым или включить его в саму программу в виде массива что ли.
Юрий теперь в порядке, но похоже проблема и с именем Ольга. Видимо и другие имена и фамилии тоже.
Также не совсем понятно как быть с файлом rules.js - он привязан к расположению экзешника, что не совсем unix way. Или сделать расположение настраиваемым или включить его в саму программу в виде массива что ли.
видимо логика не до конца реализована. в оригинальной библиотеке эвристик еще файл для определения рода (мужской, женский, средний(?)), который тут вообще не задействован. и файл с правилами более новый. Причем там он не кодированный, что проще для отладки и понимания что там внутри.Alexander писал(а):> код поправленной библиотеки:
Юрий теперь в порядке, но похоже проблема и с именем Ольга. Видимо и другие имена и фамилии тоже.
Также не совсем понятно как быть с файлом rules.js - он привязан к расположению экзешника, что не совсем unix way. Или сделать расположение настраиваемым или включить его в саму программу в виде массива что ли.
надо посмотреть у оригинала, какая должна быть логика. Что касается файла с правилами, то можно там сделать инжектированную зависимость от TStream вместо имени файла, тогда файл можно будет включить и в ресурсы программы и из файла грузить, в зависимости от конфигурации..
Я делал это для разовой задаче буквально на коленке буквально за полчаса, просто переписав на паскале php версию, и, возможно только ту её часть что была нужна мне в тот момент.
Склонялись имена правильно, но какую версию rules.json использовал сказать уже не могу.
И да, скорее всего для полноценного использования требуются доработки.
https://github.com/petrovich - если что вот здесь все её реализации на разных языках.
Склонялись имена правильно, но какую версию rules.json использовал сказать уже не могу.
И да, скорее всего для полноценного использования требуются доработки.
https://github.com/petrovich - если что вот здесь все её реализации на разных языках.
