/***************************************************************************/
// "Меркурий"-"Правда" - open source переводчик
// распространяется в соответсвии с лицензией GNU v 2.0
//
// словарь переводов слов и словосочетаний
// Анисимов Д.В. сегодня
/***************************************************************************/
# include <stdio.h>
# include <malloc.h>
# include <string.h>
# include <stdlib.h>
# include <mylib.h>
# include <grammar.h>
# include <slowo3.h>
# include <core.h>
# include <factorial.cpp>
static t_Slowo3 *Slowo3 ;
char Word0[100] ;
t_Factorial Factorial(5) ;
char *filename( char *Path, char *File );
short find_param1( t_Param1List *List, char *Str )
;
/***************************************************************************/
// инициировать нулями
/***************************************************************************/
t_Slowo3 :: t_Slowo3( void )
{
FileName[0]=0 ;
Format =NULL ;
Mass =NULL ;
Word =NULL ;
Struct =NULL ;
Record =NULL ;
Relation=NULL ;
l_Mass =0 ;
l_Mass1 =0 ;
n_Word =0 ;
n_Struct=0 ;
n_Record=0 ;
n_Tree =0 ;
n_Relation=0 ;
}
/***************************************************************************/
//
/***************************************************************************/
void t_Slowo3 :: del( void )
{
Free( Mass );
Free( Word );
Free( Struct );
Free( Record );
Free( Tree );
Free( Relation );
}
/***************************************************************************/
// записать бинарный образ
/***************************************************************************/
void t_Slowo3 :: write_bin( char *File )
{ FILE *fw ;
fw=Fopen( File,"wb" );
Fwrite( &l_Mass ,1,sizeof(long),fw );
Fwrite( &n_Word ,1,sizeof(long),fw );
Fwrite( &n_Struct ,1,sizeof(long),fw );
Fwrite( &n_Record ,1,sizeof(long),fw );
Fwrite( &n_Tree ,1,sizeof(long),fw );
Fwrite( &n_Relation,1,sizeof(long),fw );
Fwrite( Mass ,l_Mass+1 ,sizeof(char) ,fw );
Fwrite( Word ,n_Word+1 ,sizeof(t_sWord) ,fw );
Fwrite( Struct ,n_Struct+1 ,sizeof(t_sStruct) ,fw );
Fwrite( Record ,n_Record+1 ,sizeof(t_sRecord) ,fw );
Fwrite( Tree ,n_Tree ,sizeof(t_sTree) ,fw );
Fwrite( Relation,n_Relation+1,sizeof(t_Relation),fw );
Fclose( fw );
}
/***************************************************************************/
// прочитать бинарный образ
/***************************************************************************/
char t_Slowo3 :: read_bin( char *File )
{ FILE *fr ;
long i ;
try
{
fr=Fopen( File,"rb" );
del( );
Fread( &l_Mass ,1,sizeof(long),fr );
Fread( &n_Word ,1,sizeof(long),fr );
Fread( &n_Struct ,1,sizeof(long),fr );
Fread( &n_Record ,1,sizeof(long),fr );
Fread( &n_Tree ,1,sizeof(long),fr );
Fread( &n_Relation,1,sizeof(long),fr );
Mass =(uchar *)Malloc( l_Mass+1 ,sizeof(uchar));
Word =(t_sWord *)Malloc( n_Word+1 ,sizeof(t_sWord));
Struct =(t_sStruct *)Malloc( n_Struct+1 ,sizeof(t_sStruct));
Record =(t_sRecord *)Malloc( n_Record+1 ,sizeof(t_sRecord));
Tree =(t_sTree *)Malloc( n_Tree ,sizeof(t_sTree));
Relation=(t_Relation *)Malloc( n_Relation+1,sizeof(t_Relation));
Fread( Mass ,l_Mass+1 ,sizeof(char) ,fr );
Fread( Word ,n_Word+1 ,sizeof(t_sWord) ,fr );
Fread( Struct ,n_Struct+1 ,sizeof(t_sStruct) ,fr );
Fread( Record ,n_Record+1 ,sizeof(t_sRecord) ,fr );
Fread( Tree ,n_Tree ,sizeof(t_sTree) ,fr );
Fread( Relation,n_Relation+1,sizeof(t_Relation),fr );
Fclose( fr );
for( i=0 ; i<n_Struct ; i++ )
Struct[i].Word=Word+Struct[i].sy_word ;
for( i=0 ; i<n_Word ; i++ )
Word[i].str=(char *)Mass+Word[i].sy ;
l_Mass1=l_Mass ;
return 0 ;
}
catch( ... )
{
return -1 ;
}
}
/***************************************************************************/
// прочитать из текстового формата все словари,
// и сделать из них единый словарь
/***************************************************************************/
void t_Slowo3 :: read( char *Dir, t_Grammar *Gr )
{
long i,i1,j,N,j_Slowo ;
long j_Word,j_Struct,j_Record,j_Relation ;
t_File *FF ;
t_Slowo3 *Slowo3,*SS ;
t_FileList &File1=Gr->file1() ;
char Filename[200] ;
del( );
Format=&(Gr->format1()[0]) ;
for( N=i=0 ; i<File1.j ; i++ )
N+=File1[i].FileName.j ;
Slowo3=(t_Slowo3 *)Calloc( N,sizeof(t_Slowo3) );
// ------ сосчитать потребную память --------------------------
l_Mass=n_Word=n_Struct=n_Record=n_Relation=0 ;
for( j_Slowo=i=0 ; i<File1.j ; i++ )
{ FF=&File1[i] ;
for( i1=0 ; i1<FF->FileName.j ; i1++ )
{ SS=&Slowo3[j_Slowo] ;
SS->Format=&(Gr->format1()[FF->i_format]) ;
strcpy( Filename,Dir ); strcat( Filename,FF->FileName[i1] );
SS->read0( Filename );
SS->parse( );
l_Mass += SS->l_Mass ;
n_Word += SS->n_Word ;
n_Struct += SS->n_Struct ;
n_Record += SS->n_Record ;
n_Relation += SS->n_Relation ;
j_Slowo++ ;
}
}
l_Mass1=l_Mass ;
// ------ захватить память ------------------------------------
Mass =(uchar *)Calloc( l_Mass+1 ,sizeof(uchar ) );
Word =(t_sWord *)Calloc( n_Word+1 ,sizeof(t_sWord ) );
Struct =(t_sStruct *)Calloc( n_Struct+1 ,sizeof(t_sStruct) );
Record =(t_sRecord *)Calloc( n_Record+1 ,sizeof(t_sRecord) );
Relation=(t_Relation *)Calloc( n_Relation+1,sizeof(t_Relation));
// ------ переписать структуры и слова из всех словарей в один -
j=j_Word=j_Struct=j_Record=j_Relation=0 ;
for( i=0 ; i<N ; i++ )
{ SS=&Slowo3[i] ;
t_sRecord *R ;
t_sStruct *S ;
memcpy( Record+j_Record,SS->Record,SS->n_Record*sizeof(t_sRecord) );
for( i1=0 ; i1<SS->n_Record ; i1++ )
{ R=&Record[j_Record++] ;
R->sy_struct+=j_Struct ;
R->i_dict=i ;
}
memcpy( Struct+j_Struct,SS->Struct,SS->n_Struct*sizeof(t_sStruct) );
for( i1=0 ; i1<SS->n_Struct ; i1++ )
{ S=&Struct[j_Struct++] ;
S->sy_word +=j_Word ;
S->i_relation+=j_Relation ;
}
memcpy( Word+j_Word,SS->Word,SS->n_Word*sizeof(t_sWord) );
for( i1=0 ; i1<SS->n_Word ; i1++ )
Word[j_Word++].sy+=j ;
for( i1=0 ; i1<SS->n_Relation ; i1++ )
Relation[j_Relation++]=SS->Relation[i1] ;
memcpy( Mass+j,SS->Mass,SS->l_Mass );
j+=SS->l_Mass ;
}
// ----- освободить память от исходных словарей ----------------
for( i=0 ; i<N ; i++ )
Slowo3[i].del( );
Free( Slowo3 );
// ----- проставть конечные значения ---------------------------
Struct[j_Struct].sy_word =j_Word ;
Struct[j_Struct].i_relation=j_Relation ;
Record[j_Record].sy_struct =j_Struct ;
// ----- проставть ссылки куда надо ----------------------------
for( i=0 ; i<n_Struct ; i++ )
Struct[i].Word=Word+Struct[i].sy_word ;
for( i=0 ; i<n_Word ; i++ )
Word[i].str=(char *)Mass+Word[i].sy ;
split_unorder( );
sort0( );
make_tree( );
}
/***************************************************************************/
// прочесть из файла и построить все структуры
/***************************************************************************/
void t_Slowo3 :: read( char *File, t_Format1 *_Format )
{
Format = _Format ;
read0( File );
parse( );
split_unorder( );
sort0( );
make_tree( );
}
/***************************************************************************/
// прочесть из массива и построить все структуры
/***************************************************************************/
void t_Slowo3 :: make( char *_Mass, t_Format1 *_Format )
{
Format = _Format ;
make0( _Mass );
parse( );
sort0( );
make_tree( );
}
/***************************************************************************/
// прочесть из файла
/***************************************************************************/
void t_Slowo3 :: read0( char *File )
{ FILE *fr ;
try
{
fr=Fopen( File,"rb" );
l_Mass=FileLength( fr );
Mass =(uchar *)Calloc( l_Mass+1,sizeof(uchar) );
Fread( Mass,l_Mass,sizeof(uchar),fr );
fclose(fr);
l_Mass=remark( (char *)Mass, l_Mass );
}
catch( int E )
{
fprintf( File_Error,"\n Ребята, че-то я словарь %s не могу прочесть.",File );
if( E==Err_Fopen ) fprintf( File_Error,"\n А он вообще-то есть?" );
throw( E );
}
}
/***************************************************************************/
// прочесть из массива
/***************************************************************************/
void t_Slowo3 :: make0( char *_Mass )
{
l_Mass=strlen( _Mass );
Mass =(uchar *)Calloc( l_Mass+1,1 );
for( long i=0 ; i<l_Mass ; i++ )
Mass[i]=_Mass[i] ;
l_Mass=remark( (char *)Mass, l_Mass );
}
/***************************************************************************/
// построить все структуры
/***************************************************************************/
void t_Slowo3 :: parse( void )
{ long i,i1,i2,j,j1 ;
char c,Reg[100],Msg[200]="" ;
char fformat, // признак, что разбирается сложная структура
fstr, // признак, что разбирается заголовок структуры
fdst; // признак, что разбирается структура-приемник
long j_Word,j_Struct,j_Record,j_Relation ;
t_sStruct *S ;
t_sWord *W ;
try
{
// ------------ посчитать число слов и переводов -----------------
for( i=0,fformat=1 ; i<l_Mass ; i++ )
{ c=Mass[i] ;
if( c=='[' || c=='~' )
{ n_Word++ ;
n_Struct+=fformat ;
continue ;
}
if( c=='\n' ) { n_Record++ ; fformat=1 ; }
if( c==':' ) { n_Struct++ ; fformat=0 ; }
}
n_Record++ ;
// ------------ захватить память --------------------------------
Word =(t_sWord *)Calloc( n_Word+1 ,sizeof(t_sWord) );
Struct =(t_sStruct *)Calloc( n_Struct+1,sizeof(t_sStruct) );
Record =(t_sRecord *)Calloc( n_Record+1,sizeof(t_sRecord) );
Relation=(t_Relation *)Calloc( 256000 ,sizeof(t_Relation) );
for( i=0 ; i<n_Struct ; i++ )
Struct[i].Param.init();
for( i=0 ; i<n_Word ; i++ )
Word[i].Param.init();
// ---------- расставить ссылки и определить части речи ---------------
j_Word =0 ; W=Word ;
j_Struct =0 ; S=Struct ;
j_Record =0 ;
j_Relation=0 ;
char Type[256] ;
for( i=0 ; i<256 ; i++ )
Type[i]=0 ;
Type['=']=Type[';']=Type[':']=Type['~']=1 ;
Type['(']=Type[')']=Type['[']=Type[']']=Type['<']=Type['>']=1 ;
for( i=-1 ; i<l_Mass ; i++ )
{ if( i!=-1 && Mass[i]!='\n' ) continue ;
Record[j_Record++].sy_struct=j_Struct ;
fformat=fdst=fstr=0 ;
// -------- сформировать строку сообщения ------------
for( i1=i+1,j=0 ; i1<l_Mass && Mass[i1]!='\n' ; i1++ )
{ if( 198<j ) break ;
Msg[j++]=Mass[i1] ;
}
Msg[j]=0 ;
// -------- определить, является ли строка словом или структурой -------
for( i1=i+1 ; i1<l_Mass && Mass[i1]!='[' ; i1++ )
if( Mass[i1]==':' ) { fformat=fstr=1 ; break ; }
// -------- разбор строки ----------------------------
for( i1=i+1,j=0 ; i1<l_Mass && Mass[i1]!='\n' ; i1++ )
{
c=Mass[i1] ;
if( j<98 ) Reg[j++]=c ;
if( c<0 || Type[c]==0 ) continue ;
if( c=='=' )
{ fdst=1 ;
fstr=fformat ;
j=0 ;
}
if( c==';' )
{ fstr=fformat ;
j=0 ;
continue ;
}
if( fstr==1 )
{ // -------- если разбирается заголовок структуры --------
if( c==':' || c=='(')
{ short i_str ;
if( Mass[i1-1]!=')' )
{
Reg[j-1]=0 ;
for( j1=i2=0 ; i2<j ; i2++ )
if( Reg[i2]!=' ' ) Reg[j1++]=Reg[i2] ;
S->sy_word =j_Word ;
i_str=Format->find_struct( fdst,Reg );
if( i_str<=-10 )
{ fprintf( File_Error,"\n Неизвестный тэг\"%s\"\n",Reg ); throw(-1); }
S->i_struct=i_str ;
S->i_relation=j_Relation++ ;
S=Struct+(++j_Struct) ;
}
if( c==':' ) fstr=0 ;
j=0 ;
}
if( c==')' )
{ Reg[j-1]=0 ;
t_sStruct *S1=&Struct[j_Struct-1] ;
make_relation1( fdst, S1, Reg );
j=0 ;
}
}
else
{ // -------- если разбирается тело структуры --------
if( c=='[' || c=='~' )
{ short i_str ;
Reg[j-1]=0 ;
for( j1=i2=0 ; i2<j ; i2++ )
if( Reg[i2]!=' ' ) Reg[j1++]=Reg[i2] ;
i_str=Format->find_struct( fdst,Reg );
if( i_str<=-10 )
{ fprintf( File_Error,"\n Неизвестный тэг\"%s\"\n",Reg ); throw(-1); }
W->i_struct=i_str ;
j=0 ;
if( c=='[' )
{ if( fformat==0 )
{ S->sy_word =j_Word ;
S->i_struct=W->i_struct ;
S->i_relation=j_Relation++ ;
S=Struct+(++j_Struct) ;
}
W->sy=i1+1 ;
}
else
{
Mass[i1]=0 ;
W->sy=i1 ;
W=Word+(++j_Word) ;
}
continue ;
}
if( c==']' )
{ Mass[i1]=0 ;
W=Word+(++j_Word) ;
j=0 ;
continue ;
}
if( c=='(' || c=='<' )
j=0 ;
if( c=='>' )
{ Reg[j-1]=0 ; Word[j_Word-1].order=atoi(Reg); j=0 ; }
if( c==')' )
{ Reg[j-1]=0 ;
t_sStruct *S1=&Struct[j_Struct-1] ;
short iw=j_Word-S1->sy_word-1 ;
make_relation2( fdst, S1, iw, Reg, j_Relation );
j=0 ;
}
}
}
}
// ----- проставть конечные значения --------------
Struct[j_Struct].sy_word =j_Word ;
Struct[j_Struct].i_relation=j_Relation ;
Record[j_Record].sy_struct =j_Struct ;
// ----- проставть ссылки Struct[].Word -----------
for( i=0 ; i<n_Struct ; i++ )
{ Struct[i].Word=Word+Struct[i].sy_word ;
Struct[i].n_Word=Struct[i+1].sy_word-Struct[i].sy_word ;
Relation[Struct[i].i_relation].s1=Struct[i+1].i_relation-Struct[i].i_relation-1 ;
}
// ----- проставть Record[].n_struct --------------
for( i=0 ; i<n_Record ; i++ )
Record[i].n_struct=Record[i+1].sy_struct-Record[i].sy_struct ;
// ------ проверить TSTRUCT1 ----------------------
{
char f_error=0 ;
for( i=0 ; i<n_Record ; i++ )
{ t_Struct *S0 ;
for( i1=0 ; i1<Record[i].n_struct ; i1++ )
{ S=&Struct[Record[i].sy_struct+i1] ;
if( S->i_struct<0 ) continue ;
if( i1==0 ) S0=&Grammar[S->i_struct].From ;
else S0=&Grammar[S->i_struct].To ;
if( S0->type!=TSTRUCT1 ) continue ; // ABR
if( S0->Word.j!=S->n_Word )
{ fprintf( File_Error,"\n Несоответствие числа слов в Структура1");
fprintf( File_Error,"\n строка %ld",i+1 );
f_error=1 ;
}
for( i2=0 ; i2<S0->Word.j ; i2++ )
{ if( S0->Word[i2].i_struct!=S->Word[i2].i_struct )
{ fprintf( File_Error,"\n Несоответствие типов слов в Структура1");
fprintf( File_Error,"\n строка %ld",i+1 );
f_error=1 ;
}
}
}
}
if( f_error==1 ) throw(-1);
}
// ----- поджать массив Record --------------------
for( i=j_Record=0 ; i<n_Record ; i++ )
if( 0<Record[i].n_struct ) Record[j_Record++]=Record[i] ;
n_Record=j_Record ;
// ------ проставить ссылки Word[].str ------------
for( i=0 ; i<n_Word ; i++ )
Word[i].str=(char *)Mass+Word[i].sy ;
// ------ исключить нулевые строки ----------------
for( i=0 ; i<l_Mass ; i++ )
if( Mass[i]=='\n' ) Mass[i]=0 ;
Relation=(t_Relation *)Realloc( Relation,j_Relation*sizeof(t_Relation) );
n_Relation=j_Relation ;
}
catch( int E )
{
fprintf( File_Error,"\nSlowo3::Строка=\"%s\"\n",Msg );
Read_Error=-1 ;
throw( E );
}
}
/***************************************************************************/
// задать постоянные параметры заголовку структуры
// fdst - 0-источник 1-приемник
// S - заполняемая структура
// Str - строка, содержащая параметры, например "Родительный,Множественное"
/***************************************************************************/
void t_Slowo3 :: make_relation1( char fdst, t_sStruct *S, char *Str )
{
short i,j,j_param ;
char c,Str1[20] ;
S->Param.init();
for( i=j=j_param=0 ; i<100 ; i++ )
{ c=Str[i] ;
if( c==' ' ) continue ;
if( c==0 || c==',' )
{ Str1[j]=0 ; j=0 ;
S->Param.value[j_param]=find_value1( S->i_struct, j_param, fdst, Str1 ) ;
j_param++ ;
}
if( c==0 ) break ;
Str1[j++]=c ;
}
}
/***************************************************************************/
// сделать таблицу передачи параметров для структуры,
// и задать постоянные параметры
// fdst - 0-источник 1-приемник
// S - заполняемая структура
// i_word - индекс части структуры t_sStruct->Word[i_word]
// Str - строка, содержащая параметры, например "Родительный,Множественное"
// j_Relation - ссылка на первый свободный элемент в массиве Relation
/***************************************************************************/
void t_Slowo3 :: make_relation2( char fdst, t_sStruct *S, long i_word,
char *Str, long &j_Relation )
{
t_sWord *W=Word+S->sy_word+i_word ;
t_Param1List *pParam ;
t_Relation R ;
short i,i1,j,j_param,v ;
char c,Str1[20] ;
if( i_word<0 )
{ fprintf( File_Error,"\nmake_relation i_word<0 !!!\n"); throw(-1); }
W->Param.init();
for( i=j=j_param=0 ; i<100 ; i++ )
{ c=Str[i] ;
if( c==' ' ) continue ;
if( c==0 || c==',' )
{ Str1[j]=0 ; j=0 ;
v=find_value1( W->i_struct, j_param, fdst, Str1 ) ;
if( 0<=v || 0==strcmp(Str1,"@0") )
W->Param.value[j_param]=v ;
else
{
if( S->i_struct<0 )
{ fprintf( File_Error,"\nmake_relation1::S->i_struct<0"); throw(-1); }
if( fdst==0 )
pParam=&Grammar[S->i_struct].From.Param ;
else pParam=&Grammar[S->i_struct].To.Param ;
i1=find_param1( pParam, Str1 );
if( i1<0 )
{ fprintf( File_Error,"\nmake_relation2::параметр структуры не найден"); throw(-1); }
if( pParam->list[i1].Dir==1 )
{ // ----- передача параметров от структуры к ее части
R.s1=0 ;
R.p1=i1 ;
R.s2=i_word+1 ;
R.p2=j_param ;
}
else
{ // ----- передача параметров от части к структуре
R.s2=0 ;
R.p2=i1 ;
R.s1=i_word+1 ;
R.p1=j_param ;
}
Relation[j_Relation++]=R ;
}
j_param++ ;
}
if( c==0 ) break ;
if( c==',' ) continue ;
Str1[j++]=c ;
}
}
/***************************************************************************/
// найти значение грамматического параметра по имени значения
// i_struct - индекс части речи или структуры
// i_param - индекс параметра в этой структуре t_Struct->Param[i_struct]
// fdst - 0-источник 1-приемник
// Str1 - значение параметра, например "Дательный"
/***************************************************************************/
short t_Slowo3 :: find_value1( short i_struct, short i_param, char fdst, char *Str1 )
{ short v, i_rename ;
t_Param1List *pParam ;
t_ValueList *value ;
if( i_struct<0 )
{ fprintf( File_Error,"\nmake_relation2::W->i_struct<0"); throw(-1); }
if( fdst==0 )
{ pParam=&Grammar[i_struct].From.Param ;
value =&Grammar.from().Param[pParam->list[i_param].param].Value ;
}
else
{ pParam=&Grammar[i_struct].To.Param ;
value =&Grammar.to().Param[pParam->list[i_param].param].Value ;
}
if( pParam->j<=i_param )
{ fprintf( File_Error,"\nmake_relation2::pParam.j<=i_param"); throw(-1); }
i_rename=find_rename( Str1 );
if( 0<=i_rename )
v=find_value( value, Format->Rename[i_rename].Full );
else v=find_value( value, Str1 );
return v ;
}
/***************************************************************************/
//
/***************************************************************************/
short t_Slowo3 :: find_rename( char *Str )
{
for( short i=0 ; i<Format->Rename.j ; i++ )
if( 0==strcmp( Str,Format->Rename[i].Reduce ) ) return i ;
return -1 ;
}
/***************************************************************************/
// построить дерево поиска слов и выражений
/***************************************************************************/
void t_Slowo3 :: make_tree( void )
{
long i,i1,j ;
short s,s1,n ;
char *Str,*Str1 ;
t_sStruct *S,*S1 ;
t_sTree *T ;
Tree=(t_sTree *)Calloc( 4*n_Word,sizeof(t_sTree) );
Tree[0].up=-1 ;
Tree[0].down=1 ;
Tree[0].first =0 ;
Tree[0].last =n_Record ;
Tree[0].rang =-2 ;
// ----------- первый уровень - по индексам структур --------
Tree[1].first=0 ;
Tree[1].rang =-1 ;
s=Struct[Record[0].sy_struct].i_struct ;
for( i=0,j=2 ; i<n_Record ; i++ )
{ s1=Struct[Record[i].sy_struct].i_struct ;
if( s1!=s )
{ Tree[j-1].last = i-1 ;
Tree[j].first = i ;
Tree[j].rang =-1 ;
j++ ;
s=s1 ;
}
}
Tree[j-1].last=n_Record ;
Tree[0].n_down=j-1 ;
// ----------- следующие уровни - по индексам слов --------
for( i=1 ; i<j ; i++ )
{ T=&Tree[i] ;
n=T->rang+1 ;
S=&Struct[Record[T->first].sy_struct] ;
if( (T->last-T->first)<=1 && S->n_Word<=n )
{
T->down=-1 ;
T->n_down=0 ;
continue ;
}
T->down=j ;
S =&Struct[Record[T->first].sy_struct] ;
S1=&Struct[Record[T->last ].sy_struct] ;
if( S->n_Word<=n ) s =-2 ; else s =S->Word[n].i_struct ;
if( S1->n_Word<=n ) s1=-2 ; else s1=S1->Word[n].i_struct ;
if( s!=s1 )
{ // ---- структура с неодинаковыми сыновьями ----
T->empty=2 ;
s=-10 ;
for( i1=T->first ; i1<=T->last ; i1++ )
{ S=&Struct[Record[i1].sy_struct] ;
if( S->n_Word<=n ) s1=-2 ;
else s1=S->Word[n].i_struct ;
if( s1!=s )
{ if( i1!=0 && s!=-10 ) Tree[j-1].last =i1-1 ;
Tree[j].up =i ;
Tree[j].first =i1 ;
Tree[j].rang =n-1 ;
Tree[j].empty =1 ;
s=s1 ;
j++ ;
}
}
Tree[j-1].last=T->last ;
T->n_down =j-T->down ;
}
else
{ // ---- структура с одинаковыми сыновьями ----
Str="\7" ;
for( i1=T->first ; i1<=T->last ; i1++ )
{ S=&Struct[Record[i1].sy_struct] ;
if( S->n_Word<=n ) Str1="" ;
else Str1=(char *)Mass+S->Word[n].sy ;
if( 0!=Strcmp( Str1,Str ) || S->n_Word==(n+1) )
{ if( i1!=T->first ) Tree[j-1].last =i1-1 ;
Tree[j].up =i ;
Tree[j].first =i1 ;
Tree[j].rang =n ;
Str=Str1 ;
j++ ;
}
}
Tree[j-1].last=T->last ;
T->n_down =j-T->down ;
}
}
n_Tree=j ;
Tree=(t_sTree *)Realloc( Tree,j*sizeof(t_sTree));
}
/***************************************************************************/
// размножить все cтруктуры типа "беспорядок"
/***************************************************************************/
void t_Slowo3 :: split_unorder( void )
{ long i,i1,i2,f,ns,z,N ;
long j_Record, j_Struct, j_Word, j_Relation ;
long n_Record1, n_Struct1, n_Word1, n_Relation1 ;
e_Type t ;
t_sRecord *R ;
t_sStruct *S ;
n_Record1=n_Struct1=n_Word1=n_Relation1=0 ;
for( f=i=0 ; i<n_Record ; i++ )
{ S=&Struct[Record[i].sy_struct] ;
if( S->i_struct<0 ) continue ;
t=Grammar[S->i_struct].From.type ;
if( t==TUNORDER1 || t==TUNORDER2 )
{ N=Factorial.fak[S->n_Word]-1 ;
n_Record1 +=N ;
n_Struct1 +=N*Record[i].n_struct ;
n_Word1 +=N*S->n_Word ;
n_Relation1+=N*(Relation[S->i_relation].s1+1) ;
}
}
if( n_Record1==0 ) return ;
long NN =n_Record ;
j_Record =n_Record ; n_Record +=n_Record1 ;
j_Struct =n_Struct ; n_Struct +=n_Struct1 ;
j_Word =n_Word ; n_Word +=n_Word1 ;
j_Relation=n_Relation ; n_Relation+=n_Relation1 ;
Record =(t_sRecord *)Realloc( Record ,(n_Record+1)* sizeof( t_sRecord ) );
Struct =(t_sStruct *)Realloc( Struct ,(n_Struct+1)* sizeof( t_sStruct ) );
Word =(t_sWord *)Realloc( Word ,n_Word * sizeof( t_sWord ) );
Relation=(t_Relation *)Realloc( Relation,n_Relation * sizeof( t_Relation ) );
// ---- c Relation не понятно что делать
for( f=i=0 ; i<NN ; i++ )
{ R=&Record[i] ;
S=&Struct[Record[i].sy_struct] ;
if( S->i_struct<0 ) continue ;
t=Grammar[S->i_struct].From.type ;
if( t==TUNORDER1 || t==TUNORDER2 )
{ N=Factorial.fak[S->n_Word] ;
for( i1=1 ; i1<N ; i1++ )
{ Record[j_Record]=*R ;
Record[j_Record].sy_struct=j_Struct ;
Struct[j_Struct]=*S ;
Struct[j_Struct].sy_word=j_Word ;
for( i2=0 ; i2<S->n_Word ; i2++ )
{ z=Factorial.value[i1*Factorial.n+i2] ;
Word[j_Word++]=S->Word[z] ;
}
Relation[j_Relation++].s1=ns=Relation[S->i_relation].s1 ;
for( i2=0 ; i2<ns ; i2++ )
{ t_Relation R1=Relation[S->i_relation+i2+1] ;
Relation[j_Relation] =R1 ;
Relation[j_Relation].s1=Factorial.use(i1,R1.s1) ;
Relation[j_Relation].s2=Factorial.use(i1,R1.s2) ;
j_Relation++ ;
}
j_Struct++ ;
for( i2=1 ; i2<R->n_struct ; i2++ )
Struct[j_Struct++]=S[i2] ;
j_Record++ ;
}
}
if( n_Record<j_Record || n_Struct<j_Struct || n_Word<j_Word || n_Relation<j_Relation )
{ printf("\nВнутренняя ошибка в t_Slowo3 :: split_unorder\n");
exit(-1);
}
}
// ----- проставть конечные значения ---------------------------
Struct[j_Struct].sy_word =j_Word ;
Struct[j_Struct].i_relation=j_Relation ;
Record[j_Record].sy_struct =j_Struct ;
// ----- проставть ссылки куда надо ----------------------------
for( i=0 ; i<n_Struct ; i++ )
Struct[i].Word=Word+Struct[i].sy_word ;
for( i=0 ; i<n_Word ; i++ )
Word[i].str=(char *)Mass+Word[i].sy ;
}
/***************************************************************************/
// функция упорядочивания структур (больше-меньше)
/***************************************************************************/
int funk0( const void *a, const void *b )
{ t_sStruct *S1,*S2 ;
short f,iw,nw,is1,is2 ;
S1=Slowo3->sstruct((*(t_sRecord **)a)->sy_struct) ;
S2=Slowo3->sstruct((*(t_sRecord **)b)->sy_struct) ;
if( S1->i_struct!=S2->i_struct ) return S1->i_struct-S2->i_struct ;
nw=min( S1->n_Word,S2->n_Word ) ;
for( iw=0 ; iw<nw ; iw++ )
{
is1=S1->Word[iw].i_struct ;
is2=S2->Word[iw].i_struct ;
if( is1 != is2 ) return is1-is2 ;
f=Strcmp( S1->Word[iw].str,S2->Word[iw].str );
if( f!=0 ) return f ;
}
if( S1->n_Word != S2->n_Word ) return S1->n_Word - S2->n_Word ;
return (*(t_sRecord **)a)->i_dict - (*(t_sRecord **)b)->i_dict ;
}
/***************************************************************************/
// Отсортировать структуры в должном порядке
/***************************************************************************/
void t_Slowo3 :: sort0( void )
{ long i ;
t_sRecord *R, **RR ;
Slowo3=this ;
RR=(t_sRecord **)Malloc( n_Record,sizeof(t_sRecord *) );
for( i=0 ; i<n_Record ; i++ )
RR[i]=Record+i ;
qsort( RR,n_Record,sizeof(t_sRecord *),funk0 );
R =(t_sRecord *)Calloc( n_Record+1,sizeof(t_sRecord) );
for( i=0 ; i<n_Record ; i++ )
R[i]=*RR[i] ;
Free( Record ); Free( RR );
Record=R ;
}
/***************************************************************************/
// Вставить новые выражения в словарь
/***************************************************************************/
void t_Slowo3 :: add_new( char *Dir, char *str )
{
long L ;
FILE *fw ;
t_FileList &File1=Grammar.file1() ;
char *ff ;
char Str[200] ;
if( 0!=strcmp(File1[0].FileName[File1[0].FileName.j-1],"base_new.tmp" ) )
{ ff=(char *)Malloc( 20,sizeof(char) );
strcpy( ff,"base_new.tmp" );
File1[0].FileName.add( ff );
}
L=strlen( str );
fw=Fopen( filename( Dir,"base_new.tmp" ),"w" );
Fwrite( str,L,sizeof(char),fw );
Fclose( fw );
File_Error=Fopen("mercury.err","w+");
read( Dir, &Grammar );
Fclose( File_Error );
}
/***************************************************************************/
// разбиение фразы на составные части (итерационная)
/***************************************************************************/
void t_Slowo3 :: s_universe( short i_word, short i_struct )
{
long i,i1,i2,j,z,N1,i_tree ;
char *Str ;
t_sTree *T ;
t_sStruct *S ;
t_sWord *W ;
t_Variants *VV ;
t_rStruct SS ;
t_rWord R,*pR ;
t_Tree N,*pN ;
t_TreeList Node ;
if( n_Tree<=0 ) return ;
if( Core.From.j<=i_word ) return ;
i_tree=root_of_struct( i_struct );
if( i_tree<0 ) return ;
// ---- построение дерева вариантов ------
N.link=i_tree ;
N.i_last_word=i_word ;
Node.add(N);
for( i=0 ; i<Node.j ; i++ )
{ i_tree=Node[i].link ;
T=&Tree[i_tree] ;
if( Node[i].type==TNULL ) continue ; // прописать вариант
if( T->empty==2 )
{ // ---- случай с произвольными структурами и разными сыновьями ----
for( i1=0 ; i1<T->n_down ; i1++ )
{ z=T->down+i1 ;
N.type = TSTRUCT ;
N.up = i ;
N.i_word = Node[i].i_last_word ;
N.i_last_word= Node[i].i_last_word ;
N.link = z ;
N.i_struct =-1 ;
N.i_variant = 0 ;
N.index = T->rang ; // T->rang+1
N.i_slowo =-1 ;
Node.add(N);
}
continue ;
}
// --------- транслировать дальше --------------
S=Struct+Record[T->first].sy_struct ;
W=&S->Word[T->rang+1] ;
if( W->i_struct==-1 )
{ // ------ слово является константой ---------
if( Core.n_word<=Node[i].i_last_word )
Antwort.j=0 ;
else
find_bin( Core.From[Node[i].i_last_word].Str1, i_tree );
for( i1=0 ; i1<Antwort.j ; i1++ )
{ z=Antwort[i1] ;
S=Struct+Record[Tree[z].first].sy_struct ;
W=&S->Word[Tree[z].rang] ;
for( i2=j=1 ; W->str[i2]!=0 ; i2++ )
if( W->str[i2]==' ' && W->str[i2-1]!=' ' ) j++ ;
N.type = TSTRUCT ; // формальность
N.up = i ;
N.i_word = Node[i].i_last_word ;
N.i_last_word= Node[i].i_last_word+j ;
N.link = z ;
N.i_struct =-1 ;
N.i_variant = i1 ;
N.index = T->rang+1 ;
N.i_slowo =-1 ;
if( Tree[z].n_down<=0 )
N.type=TNULL ;
Node.add(N);
}
}
else
{ // ------ слово может иметь всякостные формы ------
if( Core.From.j<=Node[i].i_last_word )
continue ;
Core.universe( Node[i].i_last_word,W->i_struct );
VV=Core.variants( Node[i].i_last_word,W->i_struct );
// ---- литерал таки задан --------
// ---- вот здесь херачится большое количество ненужных вариантов
// ---- (связанных с тем, что по-русски это слово 10-ю способами переводится)
//for( i1=0 ; i1<VV->Variant.j ; i1++ )
//if( 0<VV->Variant.j )
long NN ;
if( IF_WORD( Grammar[W->i_struct].From.type ) )
NN=min( 1,VV->Variant.j ) ;
else NN=VV->Variant.j ;
for( i1=0 ; i1<NN; i1++ )
{ // ------- цикл по вариантам -------------
Str=Core.get_meaning( &VV->Variant[i1] ) ; // смысл варианта
find_bin( Str, i_tree );
for( i2=0 ; i2<Antwort.j ; i2++ )
{ z=Antwort[i2] ;
N.type = TSTRUCT ; // формальность
N.up =i ;
N.i_word =VV->Variant[i1].i_word ;
N.i_last_word=VV->Variant[i1].i_last_word ;
N.link =z ;
N.i_struct =W->i_struct ;
N.i_variant =i1 ;
N.index =T->rang+1 ;
N.i_slowo =VV->Variant[i1].i_slowo ;
if( Tree[z].n_down<=0 )
N.type=TNULL ;
Node.add(N);
}
}
}
}
// ---- собирание вариантов ----------------
t_Struct *S1=&Grammar[i_struct].From ;
VV=Core.variants( i_word, i_struct );
for( i=0 ; i<Node.j ; i++ )
{ if( Node[i].type!=TNULL ) continue ;
// ----- заполнение заголовка структуры ---------
T=&Tree[Node[i].link] ;
SS.type =S1->type ;
SS.i_word =i_word ;
SS.i_last_word=Node[i].i_last_word ;
SS.i_struct =i_struct ;
SS.r_word =Core.rWord.j ;
SS.i_slowo =T->first ;
SS.Form =Struct[Record[T->first].sy_struct].Param ;
N1=get_n_perevod( SS.i_slowo );
if( 0==is_atom(SS.i_slowo) ) // к стати сюда же логично воткнуть проверку
N1=min( 1,N1 ); // на IF_WORD а не там, где она сейчас стоит
// ---- цикл по вариантам перевода этой структуры -----
for( i1=0 ; i1<N1 ; i1++)
{
SS.i_slowo1=i1 ;
// ----- внесение, но не заполнение составляющих структуры ---
for( i2=0 ; i2<=T->rang ; i2++ )
Core.rWord.add(R);
// ----- заполнение составляющих структуры -----------------------
// ----- (в порядке задом наперед от листа дерева к его корню) ---
z=i ;
while( 1 )
{ pN=&Node[z] ;
if( Tree[pN->link].empty!=1 )
{ pR =&Core.rWord[SS.r_word+Tree[pN->link].rang] ;
if( pN->i_struct<0 )
pR->type =TCONST ;
else pR->type =Grammar[pN->i_struct].From.type ;
pR->i_word =pN->i_word ;
pR->i_last_word=pN->i_last_word ;
pR->i_struct =pN->i_struct ;
pR->i_variant =pN->i_variant ;
pR->index =pN->index ;
pR->i_slowo =pN->i_slowo ;
pR->i_slowo1 =0 ; // не уверен
}
z=pN->up ;
if( z==0 ) break ;
}
VV->Variant.add(SS);
Core.real_param_up( &VV->Variant[VV->Variant.j-1] );
}
}
}
/**************************************************************************/
// одновариантный перевод слова
// From - переводимое слово
// i_slowo - строка записи в словаре t_Slowo3->Record[i_slowo]
// i_slowo1 - вариант перевода
/**************************************************************************/
char
* t_Slowo3 :: translate_word_i( char *From, long i_slowo, short i_slowo1 )
{
strcpy( Word0,From );
if( i_slowo<0 ) return Word0 ;
t_sStruct *S=&Struct[Record[i_slowo].sy_struct+1+i_slowo1] ;
Word0[0]=0 ;
for( short i=0 ; i<S->n_Word ; i++ )
{ strcat( Word0,S->Word[i].str );
if( i<S->n_Word-1 ) strcat( Word0," " );
}
//strcpy( Word0,(char *)Mass+Struct[Record[i_slowo].sy_struct+1+i_slowo1].Word[0].sy );
return Word0 ;
}
/**************************************************************************/
// одновариантный перевод слова
// From - переводимое слово
// i_struct - часть речи, которой должно быть это слово
// i_slowo1 - вариант перевода
/**************************************************************************/
char
* t_Slowo3 :: translate_word_s( char *From, short i_struct, short i_slowo1 )
{
t_longList Ant ;
e_Type t ;
long a ;
if( 0<=i_struct )
{ t=Grammar[i_struct].To.type ;
if( t==TSTRUCT1 || t==TSTRUCT2 )
{ strcpy( Word0,"" ); return Word0 ; }
if( Grammar[i_struct].To.type!=TWORD )
return NULL ; // признак неправильного вызова
}
strcpy( Word0,From );
if( n_Tree<=0 ) return Word0 ;
find( From, i_struct, &Ant );
if( Antwort.j<=0 ) return Word0 ; // такого слова нет в словаре
a=Antwort[0] ;
if( Record[a].n_struct<=i_slowo1+1 ) i_slowo1=0 ;
strcpy( Word0,(char *)Mass+Struct[Record[a].sy_struct+1+i_slowo1].Word[0].sy );
return Word0 ;
}
/***************************************************************************/
// найти слово в дереве
// From1 - искомое слово
// i_struct - требуемая часть речи
// *_a, *_b диапазон номеров в t_sRecord встречается это слово
/***************************************************************************/
void t_Slowo3 :: find( char *From1, short i_struct, t_longList *Ant )
{
long i,zz ;
Antwort.j=0 ;
Ant->j=0 ;
if( From1[0]==0 ) return ;
if( n_Tree<=0 ) return ;
zz=root_of_struct( i_struct );
if( zz<0 ) return ;
find_bin( From1, zz );
for( i=0 ; i<Antwort.j ; i++ )
{ Antwort[i]=Tree[Antwort[i]].first ;
Ant->add( Antwort[i] );
}
}
/***************************************************************************/
// найти СТРУКТУРУ в дереве, начиная с определенной ветки
// если не получилось, укоротить выражение, до тех пор пока не найдется
// From1 - искомое слово
// zz - ветка начала поиска
/***************************************************************************/
char t_Slowo3 :: find_bin( char *From1, long zz )
{
long i ;
char From2[100] ;
Antwort.j=0 ;
for( i=0 ; i<100 ; i++ )
{ if( From1[i]==0 )
{ From2[i]=0 ; find_bin1( From2, zz ); break ; }
if( From1[i]==' ' )
{ From2[i]=0 ;
if( 0==find_bin1( From2, zz ) ) break ;
From2[i]=' ' ;
}
From2[i]=From1[i] ;
}
if( Antwort.j<=0 ) return -1 ;
return 0 ;
}
/***************************************************************************/
// найти СТРУКТУРУ в дереве, начиная с определенной ветки
// и без всяких хитростев сказать, есть оно в словаре или нет
// From1 - искомое слово
// i_tree - ветка начала поиска
/***************************************************************************/
char t_Slowo3 :: find_bin1( char *From1, long i_tree )
{
long a,b,b1,c,i,L,L1 ;
char f, *Str ;
char ff=0 ; // факт наличия строки влючающей в себя Form1
L=strlen(From1);
a=Tree[i_tree].down ;
b=b1=a+Tree[i_tree].n_down-1 ;
while( 1 )
{
if( b-a<4 )
{ for( i=a ; i<=b ; i++ )
if( 0==Strncmp( From1,word_src(i),L ) ) break ;
a=i ;
break ;
}
c=(a+b)/2 ;
f=Strncmp( From1,word_src( c ),L );
if( f<0 ) b=c ;
if( f>0 ) a=c ;
if( f==0 )
{ for( i=c ; a<i ; i-- )
if( 0!=Strncmp( From1,word_src(i),L) ) { a=i+1 ; break ; }
break ;
}
}
for( i=a ; i<=b && i<=b1 ; i++ )
{ Str=word_src(i);
f=Strncmp( From1,Str,L );
if( 0>f ) break ;
L1 =strlen(Str);
if( L==L1 ) Antwort.add(i) ;
else ff=1 ;
if( 0==L && 0<L1 ) break ;
}
return ff ;
}
/***************************************************************************/
// найти ветвь в дереве, с которой начинаются структуры типа i_struct
/***************************************************************************/
long t_Slowo3 :: root_of_struct( short i_struct )
{ long i ;
for( i=0 ; i<Tree[0].n_down ; i++ )
if( Struct[Record[Tree[1+i].first].sy_struct].i_struct==i_struct )
return i+1 ;
return -1 ;
}
/***************************************************************************/
// какими частями речи является слово From
/***************************************************************************/
short t_Slowo3 :: part( char *From, short *i_Part )
{ short i,j ;
t_sStruct *S ;
t_longList Ant ;
if( n_Tree<=0 ) return j ;
for( i=j=0 ; i<Tree[0].n_down ; i++ )
{
S=Struct+Record[Tree[1+i].first].sy_struct ;
if( S->i_struct<0 ) continue ;
if( Grammar[S->i_struct].From.type!=TWORD ) continue ;
find( From, S->i_struct,&Ant );
if( 0<Ant.j )
i_Part[j++]=S->i_struct ;
}
return j ;
}
/***************************************************************************/
// постоянные параметры структуры i_slowo
/***************************************************************************/
t_Form t_Slowo3 :: struct_param( long i_slowo, long i_variant )
{
t_Form Form0 ;
t_sStruct *S ;
if( i_slowo<0 || n_Record<=i_slowo ) return Form0 ;
if( i_variant==-1 )
S=&Struct[Record[i_slowo].sy_struct] ;
else S=&Struct[Record[i_slowo].sy_struct+1+i_variant] ;
return S->Param ;
}
/***************************************************************************/
// постоянные параметры слова i_slowo
/***************************************************************************/
t_Form t_Slowo3 :: word_param( long i_slowo, long i_variant, long i_word )
{
t_Form Form0 ;
t_sStruct *S ;
if( i_slowo<0 || n_Record<=i_slowo ) return Form0 ;
if( i_variant<-1 || Record[i_slowo].n_struct<=i_variant-1 ) return Form0 ;
if( i_variant==-1 )
S=&Struct[Record[i_slowo].sy_struct] ;
else S=&Struct[Record[i_slowo].sy_struct+1+i_variant] ;
if( i_word<0 || S->n_Word<=i_word ) return Form0 ;
return S->Word[i_word].Param ;
}
/***************************************************************************/
//
/***************************************************************************/
t_Format1 * t_Slowo3 :: format( void )
{
return Format ;
}
/***************************************************************************/
//
/***************************************************************************/
t_sRecord * t_Slowo3 :: record( long i_record )
{
return &Record[i_record] ;
}
/***************************************************************************/
//
/***************************************************************************/
long t_Slowo3 :: n_record( void )
{
return n_Record ;
}
/***************************************************************************/
// есть ли у данной конструкции неатомарные потомки
// возвращает 1 если есть
/***************************************************************************/
char t_Slowo3 :: is_atom( long i_record )
{
if( i_record<0 ) return 1 ;
t_sStruct *S=&Struct[Record[i_record].sy_struct] ;
for( long i=0 ; i<S->n_Word ; i++ )
{ if( S->Word[i].i_struct<0 ) continue ;
e_Type t=Grammar[S->Word[i].i_struct].From.type ;
if( IF_CONSTR(t) ) return 1 ;
}
return 0 ;
}
/***************************************************************************/
// элемент дерева переводов
/***************************************************************************/
t_sTree * t_Slowo3 :: tree( long i_tree )
{
return &Tree[i_tree] ;
}
/***************************************************************************/
//
/***************************************************************************/
t_sStruct * t_Slowo3 :: sstruct( long i_struct )
{
return &Struct[i_struct] ;
}
/***************************************************************************/
// дать переводимую структуру
/***************************************************************************/
t_sStruct * t_Slowo3 :: get_from( long i_slowo )
{
if( i_slowo<0 || n_Record<=i_slowo ) return NULL ;
return &Struct[Record[i_slowo].sy_struct] ;
}
/***************************************************************************/
// перевод структуры
// i_slowo - индекс переводимой строки
// i_variant - вариант перевода
/***************************************************************************/
t_sStruct * t_Slowo3 :: get_to( long i_slowo, long i_variant )
{
if( i_slowo<0 || n_Record<=i_slowo ) return NULL ;
if( Record[i_slowo].n_struct<i_variant+1 ) i_variant=0 ;
return &Struct[Record[i_slowo].sy_struct+1+i_variant] ;
}
/***************************************************************************/
// передача параметров
// i_slowo - индекс переводимой строки
// i_variant - вариант перевода (-1 - оригинал)
/***************************************************************************/
t_RelationList1 t_Slowo3 :: get_relation( long i_slowo, long i_variant )
{
t_RelationList1 RL ;
t_sStruct *S ;
if( i_slowo<0 || n_Record<=i_slowo ) return RL ;
if( i_variant==-1 )
S=&Struct[Record[i_slowo].sy_struct] ;
else S=&Struct[Record[i_slowo].sy_struct+1+i_variant] ;
RL.list =Relation+S->i_relation+1 ;
RL.j=Relation[S->i_relation].s1 ;
return RL ;
}
/***************************************************************************/
// дать число возможных переводов по индексу структуры
// типа "голова" и "жопа"
/***************************************************************************/
short t_Slowo3 :: get_n_perevod( long i_slowo )
{
return Record[i_slowo].n_struct-1 ; // ABR
}
/***************************************************************************/
// дать слово по индексу дерева
/***************************************************************************/
char
* t_Slowo3 :: word_src( long i_tree )
{
if( i_tree<0 || n_Tree<=i_tree )
{ printf("\n Error t_Slowo3 :: word_src") ; throw(-1) ; }
return (char *)Mass+Struct[Record[Tree[i_tree].first].sy_struct].Word[Tree[i_tree].rang].sy ;
}
/***************************************************************************/
// дать слово по индексу структуры
/***************************************************************************/
char
* t_Slowo3 :: word_src1( long i_slowo )
{
return (char *)Mass+Struct[Record[i_slowo].sy_struct].Word[0].sy ;
}
/***************************************************************************/
// напечатать строку словаря
/***************************************************************************/
void t_Slowo3 :: print_record( FILE *fw, long i_record )
{
t_sRecord *R=&Record[i_record] ;
t_sStruct *S ;
long i,j,is ;
fprintf( fw,"\n" );
S=&Struct[R->sy_struct];
fprintf( fw,"%s:",Format->get_tag(0,S->i_struct) );
print_param( fw,0,S->i_struct, S->Param );
for( i=0 ; i<S->n_Word ; i++ )
{
is=S->Word[i].i_struct ;
if( is<0 ) fprintf( fw,"@0" ) ;
else fprintf( fw,"%s",Format->get_tag(0,is) );
if( S->Word[i].str[0]==0 ) fprintf( fw,"~ ") ;
else fprintf( fw,"[%s] ",S->Word[i].str ) ;
print_param( fw,0,S->Word[i].i_struct, S->Word[i].Param );
}
fprintf( fw,"=" );
for( j=1 ; j<R->n_struct ; j++ )
{
S=&Struct[R->sy_struct+j] ;
if( 1<j ) fprintf( fw,";" );
fprintf( fw,"%s:",Format->get_tag(1,S->i_struct) );
print_param( fw,1,S->i_struct, S->Param );
for( i=0 ; i<S->n_Word ; i++ )
{
is=S->Word[i].i_struct ;
if( is<0 ) fprintf( fw,"@0" );
else fprintf( fw,"%s",Format->get_tag(1,is) );
if( S->Word[i].str[0]==0 ) fprintf( fw,"~ " );
else fprintf( fw,"[%s] ",S->Word[i].str );
print_param( fw,1,S->Word[i].i_struct, S->Word[i].Param );
}
}
}
/***************************************************************************/
// напечатать параметры
/***************************************************************************/
void t_Slowo3 :: print_param( FILE *fw, char to, short i_struct, t_Form &Param )
{
short i,ip ;
char *s ;
fprintf( fw,"(" );
for( i=0 ; i<10 ; i++ )
{ if( Param.value[i]<0 ) break ;
if( to==0 )
{ if( Grammar[i_struct].From.Param.j<=i ) break ;
ip=Grammar[i_struct].From.Param[i].param ;
s =Grammar.from().Param[ip].Value[Param.value[i]].Name;
}
else
{ if( Grammar[i_struct].To.Param.j<=i ) break ;
ip=Grammar[i_struct].To.Param[i].param ;
s =Grammar.to().Param[ip].Value[Param.value[i]].Name;
}
if( 0<i ) fprintf( fw,"," );
fprintf( fw,s );
}
fprintf( fw,")" );
}