/***************************************************************************/ // "Меркурий"-"Правда" - open source переводчик // распространяется в соответсвии с лицензией GNU v 2.0 // // словарь переводов слов и словосочетаний // Анисимов Д.В. сегодня /***************************************************************************/ # include # include # include # include # include # include # include # include # define DELTA_MASS 1000 # define DELTA_WORD 100 # define DELTA_STRUCT 40 # define DELTA_RECORD 10 # define DELTA_REL 50 static t_Slowo3 *Slowo3 ; char Word0[100] ; t_Factorial Factorial(5) ; char *filename( char *Path, char *DirLang, char *File ); short find_param1( t_Param1List *List, char *Str ); int funk0( const void *a, const void *b ); /***************************************************************************/ // инициировать нулями /***************************************************************************/ t_Slowo3 :: t_Slowo3( void ) { FileName[0]=0 ; Format =NULL ; Mass =NULL ; Word =NULL ; Struct =NULL ; Record =NULL ; Relation=NULL ; n_Mass = l_Mass = 0 ; n_Word = l_Word = 0 ; n_Struct = l_Struct = 0 ; n_Record = l_Record = 0 ; n_Tree = l_Tree = 0 ; n_Relation= l_Relation= 0 ; short i ; for( i=0 ; i<256 ; i++ ) Type[i]=0 ; Type['=']=Type[';']=Type[':']=Type['~']=1 ; Type['(']=Type[')']=Type['[']=Type[']']=Type['<']=Type['>']=1 ; } /***************************************************************************/ // /***************************************************************************/ 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( &n_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 ,n_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( &n_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( n_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 ,n_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 ; ifile1() ; char Filename[300] ; del( ); Format=&(Gr->format1()[0]) ; for( N=i=0 ; iFileName.j ; i1++ ) { SS=&Slowo3[j_Slowo] ; SS->Format=&(Gr->format1()[FF->i_format]) ; Strcpy( Filename,Dir,300 ); if( Filename[strlen(Filename)-1]!='/' ) Strcat( Filename,"/",300 ); Strcat( Filename,FF->FileName[i1],300 ); SS->read0( Filename ); SS->parse( ); n_Mass += SS->n_Mass ; n_Word += SS->n_Word ; n_Struct += SS->n_Struct ; n_Record += SS->n_Record ; n_Relation += SS->n_Relation ; j_Slowo++ ; } } // ------ захватить память ------------------------------------ l_Mass = n_Mass ; l_Word = n_Word ; l_Struct = n_Struct ; l_Record = n_Record ; l_Relation = n_Relation ; if( 1 ) // Ой, что это?!! { l_Mass += DELTA_MASS ; l_Word += DELTA_WORD ; l_Struct += DELTA_STRUCT ; l_Record += DELTA_RECORD ; l_Relation += DELTA_REL ; } Mass =(uchar *)Calloc( l_Mass+1 ,sizeof(uchar ) ); Word =(t_sWord *)Calloc( l_Word+1 ,sizeof(t_sWord ) ); Struct =(t_sStruct *)Calloc( l_Struct+1 ,sizeof(t_sStruct) ); Record =(t_sRecord *)Calloc( l_Record+1 ,sizeof(t_sRecord) ); Relation=(t_Relation *)Calloc( l_Relation+1,sizeof(t_Relation)); // ------ переписать структуры и слова из всех словарей в один - j=j_Word=j_Struct=j_Record=j_Relation=0 ; for( i=0 ; iRecord,SS->n_Record*sizeof(t_sRecord) ); for( i1=0 ; i1n_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 ; i1n_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 ; i1n_Word ; i1++ ) Word[j_Word++].sy+=j ; for( i1=0 ; i1n_Relation ; i1++ ) Relation[j_Relation++]=SS->Relation[i1] ; memcpy( Mass+j,SS->Mass,SS->n_Mass ); j+=SS->n_Mass ; } // ----- освободить память от исходных словарей ---------------- for( i=0 ; i']=1 ; for( i=-1 ; ii_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 ; i2Word.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 ; isy_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 ; i2find_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 ; } } } } /***************************************************************************/ // задать постоянные параметры заголовку структуры // 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] ; t_Form F ; for( i=j=j_param=0 ; i<100 ; i++ ) { c=Str[i] ; if( c==' ' ) continue ; if( c==0 || c==',' ) { Str1[j]=0 ; j=0 ; F.value[j_param]=find_value1( S->i_struct, j_param, fdst, Str1 ) ; j_param++ ; } if( c==0 ) break ; if( c==',' ) continue ; Str1[j++]=c ; } S->Param=F ; } /***************************************************************************/ // сделать таблицу передачи параметров для структуры, // и задать постоянные параметры // 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 ; t_Form F ; 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); } F.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") ) F.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 ; } W->Param=F ; } /***************************************************************************/ // найти значение грамматического параметра по имени значения // 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 ; if( i_param<0 || pParam->j<=i_param ) { fprintf( File_Error,"\nmake_relation2::i_param Error"); throw(-1); } value =&Grammar.from().Param[pParam->list[i_param].param].Value ; } else { pParam=&Grammar[i_struct].To.Param ; if( i_param<0 || pParam->j<=i_param ) { fprintf( File_Error,"\nmake_relation2::i_param Error"); throw(-1); } 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 ; iRename.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 ; Free(Tree); Tree=(t_sTree *)Calloc( 2+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 ; irang+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 ; ii_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 ; ii_struct<0 ) continue ; t=Grammar[S->i_struct].From.type ; if( t==TUNORDER1 || t==TUNORDER2 ) { N=Factorial.fak[S->n_Word] ; for( i1=1 ; i1n_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 ; i2i_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 ; i2n_struct ; i2++ ) Struct[j_Struct++]=S[i2] ; j_Record++ ; } } if( n_Recordsstruct((*(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 ; iwWord[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 ; iDir ); fw=Fopen( Str,"w" ); Fwrite( str,L,sizeof(char),fw ); Fclose( fw ); File_Error=Fopen("mercury.err","w+"); read( Dir, &Grammar ); Fclose( File_Error ); } /************************************************************************/ // вычислить насколько увеличатся массивы при добавлении выражения /************************************************************************/ void t_Slowo3 :: calc_delta( char *Str, long &d_Word, long &d_Struct ) { long i ; char c, fformat ; d_Word=0 ; d_Struct=0 ; for( i=0,fformat=1 ; Str[i]!=0 && Str[i]!='\n' ; i++ ) { c=Str[i] ; if( c=='[' || c=='~' ) { d_Word++ ; d_Struct+=fformat ; continue ; } if( c==':' ) { d_Struct++ ; fformat=0 ; } } } /***************************************************************************/ // Вставить новые выражения в словарь /***************************************************************************/ void t_Slowo3 :: add_new1( char *Str ) { long i,z,L,L1 ; long z_Mass,z_Word,d_Word,d_Struct ; t_sRecord R ; // ---------- вставить строку в массив ---------------- L=strlen( Str ); z_Mass=n_Mass ; if( l_Mass-n_Massempty==2 ) { // ---- случай с произвольными структурами и разными сыновьями ---- for( i1=0 ; i1n_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 ; i1Word[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 ; i1Variant.j ; i1++ ) //if( 0Variant.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 ; i1Variant[i1] ) ; // смысл варианта find_bin( Str, i_tree ); for( i2=0 ; i2Variant[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 ; itype ; 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.form() ; N1=get_n_perevod( SS.i_slowo ); if( 0==is_atom(SS.i_slowo) ) // к стати сюда же логично воткнуть проверку N1=min( 1,N1 ); // на IF_WORD а не там, где она сейчас стоит // ---- цикл по вариантам перевода этой структуры ----- for( i1=0 ; i1rang ; 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 ; in_Word ; i++ ) { strcat( Word0,S->Word[i].str ); if( in_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 ; iadd( 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 ; af ) break ; L1 =strlen(Str); if( L==L1 && f==0 ) Antwort.add(i) ; else ff=1 ; if( 0==L && 0=funk0( &r1, &r2 ) ) return i ; } return i ; // "аварийный" индекс } c=(a+b)/2 ; r1=&R ; r2=&Record[c] ; f=funk0( &r1,&r2 ); if( f<0 ) b=c ; if( f>0 ) a=c ; if( f==0 ) { for( i=c ; ai_struct<0 ) continue ; if( Grammar[S->i_struct].From.type!=TWORD ) continue ; find( From, S->i_struct,&Ant ); if( 0i_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.form() ; } /***************************************************************************/ // постоянные параметры слова 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.form() ; } /***************************************************************************/ // /***************************************************************************/ 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 ; in_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 :: 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_structi_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( char *File ) { FILE *fw=Fopen( File,"w" ); for( long i=0 ; isy_struct]; SS=&Grammar[S->i_struct].From ; // ------- язык оригинала ---------------------------- if( SS->type!=TWORD ) { // ------ напечатать заголовок структуры ---------- fprintf( fw,"%s",Format->get_tag(0,S->i_struct) ); print_param( fw,0,S, 0 ); fprintf( fw,":" ); } for( i=0 ; in_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 ) ; if( 0Word[i].order ) printf("<%d>",S->Word[i].order ); print_param( fw,0,S, i+1 ); if( in_Word-1 ) fprintf( fw," ") ; } fprintf( fw,"=" ); // ------- язык перевода ---------------------------- for( j=1 ; jn_struct ; j++ ) { S=&Struct[R->sy_struct+j] ; if( 1type!=TWORD ) { // ------ напечатать заголовок структуры ---------- fprintf( fw,"%s",Format->get_tag(1,S->i_struct) ); print_param( fw,1,S, 0 ); fprintf( fw,":" ); } for( i=0 ; in_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 ); if( 0Word[i].order ) printf("<%d>",S->Word[i].order ); print_param( fw,1,S, i+1 ); if( in_Word-1 ) fprintf( fw," ") ; } } } /***************************************************************************/ // напечатать параметры // i_struct0 - тип заголовка структуры // i_word - номер слова в структуре(начинается с 1) /***************************************************************************/ void t_Slowo3 :: print_param( FILE *fw, char to, t_sStruct *S, short i_word ) { short i,i1,ip,n ; short i_struct ; char *s ; t_Form Param ; t_Struct *SS ; t_Relation *RR ; n =Relation[S->i_relation].s1 ; RR=&Relation[S->i_relation+1] ; if( i_word==0 ) { i_struct=S->i_struct ; Param =S->Param.form() ; } else { i_struct=S->Word[i_word-1].i_struct ; Param =S->Word[i_word-1].Param.form() ; } if( to==0 ) SS=&Grammar[S->i_struct].From ; else SS=&Grammar[S->i_struct].To ; for( i1=i=0 ; i<10 ; i++ ) if( 0<=Param.value[i] ) i1++ ; for( i=0 ; iRename.j ; i1++ ) if( 0==strcmp(Format->Rename[i1].Full,s) ) { s=Format->Rename[i1].Reduce ; break ; } if( 0Param[i].Name ; else s=SS->Param[RR[i1].p2].Name ; goto M_continue ; } if( RR[i1].s2==i_word && RR[i1].p2==i ) { if( i_word==0 ) s=SS->Param[i].Name ; else s=SS->Param[RR[i1].p1].Name ; goto M_continue ; } } break ; M_continue :; if( 0