C/C++:
HGREN_RESPACK sol_SyntaxAnalysis( HGREN hEngine, const wchar_t * Sentence, int MorphologicalFlags, int SyntacticFlags, int LanguageID )
HGREN_RESPACK sol_SyntaxAnalysis8( HGREN hEngine, const char * SentenceUtf8, int MorphologicalFlags, int SyntacticFlags, int LanguageID )
HGREN_RESPACK sol_SyntaxAnalysisA( HGREN hEngine, const char * Sentence, int MorphologicalFlags, int SyntacticFlags, int LanguageID )
C#:
IntPtr sol_SyntaxAnalysis( IntPtr hEngine, string Sentence, int MorphologicalFlags, int SyntacticFlags, int LanguageID )
Delphi:
function sol_SyntaxAnalysis( hEngine: PInteger; Sentence: PWideChar; MorphologicalFlags: Integer; SyntacticFlags: Integer; LanguageID: Integer ): PInteger;
PHP:
sol_SyntaxAnalysis8( $hEngine, $Sentence, $MorphologicalFlags, $SyntacticFlags, $LanguageID )
Аргументы:
hEngine - дескриптор экземпляра грамматического словаря.
Sentence - указатель на строку из широких символов, из которой будет извлечен список лексем. Для функций с суффиксом 8 и A строка должна быть в кодировке utf-8 или текущей системной однобайтовой соответственно.
MorphologicalFlags - флаги, управляющие работой морфологического анализатора. Может иметь значение 0 для базового алгоритма анализа или быть побитовым объединением следующих значений:
SOL_GREN_ALLOW_FUZZY - разрешено использовать алгоритмы нечеткого морфологического анализа слов в случаях, когда анализатор встречает неизвестное ему слово. Также этот флаг разрешает применять разнообразные правила определения морфологических признаков слова по его аффиксу. Может несколько понизить производительность.
SOL_GREN_COMPLETE_ONLY - используется главным образом для автоматизированных тестов; задает требование, чтобы анализатор нашел правило, описывающее структуру всего предложения, иначе считать анализ невыполненным.
SOL_GREN_PRETOKENIZED - вместо использования внутреннего токенизатора использовать символ с кодом 0x1F как указатель границ слов. Это позволяет разбить предложение по своим правилам, если имеющиеся в словаре не устраивают, или нет возможности модифицировать словарь.
SyntacticFlags - флаги, управляющие работой синтаксического анализатора. По умолчанию должен быть задан как 0.
LanguageID - id (первичный ключ) объявления языка, на котором записано разбираемое предложение. Можно задать -1 для автоматического определения языка.
Возвращает:
Дескриптор объекта, хранящего результаты синтаксического разбора. После окончания работы с результатами его нужно удалить вызовом функции sol_DeleteResPack.
Синтаксический разбор предложения включает в себя несколько этапов, каждый из которых можно выполнить отдельно с помощью специальной функции API. Сначала предложение разбивается на слова в токенизаторе. Затем выполняется морфологический анализ, в ходе которого для каждого слова определяется его часть речи и грамматические признаки, к примеру падеж, род, число, время, степень и так далее. Наконец, начинается собственно синтаксический разбор, в ходе которого определяются синтаксические отношения слов в предложении и создается синтаксический граф.
Для работы с результатами синтаксического разбора следует использовать функции sol_CountGrafs, sol_CountRoots, sol_GetRoot, sol_CountLeafs, sol_GetLeaf, sol_GetNodeIEntry, sol_GetNodeVerIEntry, sol_GetNodePosition, sol_GetNodeContents, sol_GetNodeCoordState, sol_GetNodeVersionCount, sol_GetNodeCoordPair, sol_GetNodeVerCoordPair, sol_GetNodePairsCount, sol_GetNodeVerPairsCount, sol_GetNodePairCoord, sol_GetNodeVerPairCoord, sol_GetNodePairState, sol_GetNodeVerPairState.
Обычно порядок разбора результатов такой. Просматриваем альтернативные списки деревьев с помощью sol_CountLeafs и sol_CountRoots. В случае полностью завершенного морфологического и синтаксического анализа получается 1 набор графов, в котором ровно 3 корневых узла. Другими словами, функция sol_CountGrafs вернет 1, а sol_CountRoots(...,0) вернет 3. Первый и последний узлы являются специальными метками начала и конца анализируемого предложения, вставляются грамматическим движком и не должны приниматься в расчет прикладным кодом. Средний узел этого набора графов является корневым узлом синтаксического дерева, например глаголом для простых предложений с глагольным сказуемым. Например, предложение Большой кот сладко спит на старом кожаном диване даст такие результаты:
Видно, что корневой узел синтаксического дерева соответствует глаголу спит, к которому с помощью ребер разного типа прикреплены другие члены предложения.
Функция sol_CountLeafs может вернуть число больше 1, это значит, что некоторые части предложения допускают неоднозначную токенизацию. Например, если в предложении есть фрагмент да и, то он может быть распознан и как один союз, и как два отдельных союза. Из-за этого в результатах появляется два альтернативных набора синтаксических деревьев. В прикладном коде можно выбрать для дальнейшего анализа один из них, например - самый короткий. Другими словами, пройдя по набору альтернативных список и проверив длину каждого из них с помощью sol_CountRoots, выбираем список с минимальным числом корневых узлов. Таким способом мы получим в большинстве случаев результат с наиболее глубоко выплненным анализом. В качестве пояснения запустите отладочную консоль морфологического анализатора с помощью скрипта ...\scripts\syntax\console-morphology.cmd и введите словосочетание много, да и дешево. Результаты будут такими:
Далее можно пройтись по всем корням выбранного набора графов, используя функции sol_CountRoots и sol_GetRoot. Вторая функция возвращает дескриптор узла. Получив дескриптор корневого узла, можно определить число прикрепленных к нему веток с помощью sol_CountLeafs, и рекурсивно пройтись по этим веткам, получая в цикле дескрипторы узлов с помощью sol_GetLeaf. Детальный анализ содержимого каждого узла выполняется функциями из ранее указанного набора.
Параметр LanguageID определяет набор правил, которые будут загружены из словарной базы данных для токенизации, морфологического и синтаксического анализа. Если вместо константы языка указать -1, то движок сам определит язык предложения. На распознавание языка потребуется определенное время, поэтому следует явно указывать id языка в случаях, когда он известен априори.
C++:
HGREN_RESPACK hPack = sol_SyntaxAnalysis8( hEngine, Sentence, MorphologicalFlags, SyntacticFlags, 1000000, id_language );
const int ngrafs = sol_CountGrafs(hPack);
// Выберем среди результатов альтернативу с минимальным количеством корневых
// узлов. Два узла присутствуют в каждой альтернативе - это метки начала $BEGIN$
// и конца $END$. В случае полностью успешного анализа альтернатива имеет 3
// корневых узла - средний узел представляет из себя искомое синтаксическое дерево.
int imin_graf=-1, minv=1000000;
for( int i=0; i<ngrafs; i++ )
{
const int nroots = sol_CountRoots(hPack,i);
if( nroots<minv )
{
minv = nroots;
imin_graf = i;
}
}
// работаем с самой короткой альтернативой
const int nroot = sol_CountRoots(hPack, imin_graf);
for( int i=1; i<nroot-1; ++i )
{
HGREN_TREENODE hNode = sol_GetRoot( hPack, imin_graf, i );
...
}
sol_DeleteResPack( hPack );
C#:
IntPtr hPack = GrammarEngine.sol_SyntaxAnalysis( hEngine, text, GrammarEngine.SOL_GREN_ALLOW_FUZZY, 2, 60000, GrammarEngineAPI.RUSSIAN_LANGUAGE );
int nroot = GrammarEngine.sol_CountRoots( hPack, 0 );
for( int iroot=1; iroot<nroot-1; ++iroot )
{
IntPtr hRoot = GrammarEngine.sol_GetRoot( hPack, 0, iroot );
...
}
GrammarEngine.sol_DeleteResPack(hPack);
Delphi:
hPack := sol_SyntaxAnalysisA( hEngine, PAnsiChar('Толстый пушистый кот сладко спит на диване'), 0, 0, 100000, RUSSIAN_LANGUAGE );
nlinkage := sol_CountGrafs( hPack );
for ilinkage:=0 to nlinkage-1
do begin
nroot := sol_CountRoots( hPack, ilinkage );
for iroot:=1 to nroot-2
do begin
hNode := sol_GetRoot( hPack, ilinkage, iroot );
PrintNode( hEngine, hNode );
end;
WriteLn('');
end;
sol_DeleteResPack(hPack);
Приобретение SDK грамматического словаря
API layer C++ source code: grammar_engine_api.cpp
Вернуться к списку функций API
© Elijah Koziev 2010
Поисковая система
SDK Поисковой системы
Экранный переводчик
|
|
изменено 05-Dec-11 | ||||||||||||||||||||||||||||||||||||||