/***************************************************************************/
// "Меркурий"-"Правда" - open source переводчик
// распространяется в соответсвии с лицензией GNU v 2.0
//
// Структуры, описывающие грамматику
// Анисимов Д.В. сегодня
/***************************************************************************/
# include <stdio.h>
# include <malloc.h>
# include <string.h>
# include <stdlib.h>
# include <mylib.h>
# include <lexer.h>
# include <grammar.h>
# define Ifstr( a,b ) if( 0==strcmp(a,b) )
short find_param1( t_Param1List *List, char *Str );
short find_value2( t_strList *List, char *Str );
short find_part( t_StructList *List, char *Str );
void zerstoren_param( char *Str, char *Dir, char **Str1 );
void zerstoren_word( char *Str, char *Imp, char **Str1 );
char tst_const( t_Word *W, long i_str );
t_Grammar Grammar ; // все данные, относящиеся к грамматике
t_Lexer Lexer ; // Лексер, который разбирает lang.txt
FILE *File_Error=NULL ; // Файл, в который пишутся ошибки lang.txt
char Read_Error=0 ; // Есть ли в lang.txt ошибки
/****************************************************************************/
// прочесть все из файла и построить все индексы
// File - имя файла lang.txt с путем
/****************************************************************************/
char t_Grammar :: make_all( char *File )
{
try
{
del( );
Read_Error=0 ;
File_Error=Fopen("mercury.err","w");
read( File );
make_index( );
for( short i1=0 ; i1<Format1.j ; i1++ )
Format1[i1].make_part( this ) ;
Fclose( File_Error );
// ----------- определить какая часть речи - числительное ------
i_Number=0 ;
for( short i=0 ; i<From.Part.j ; i++ )
if( 0==strcmp( From.Part[i].Name,"числительное" ) )
{ i_Number=i ; break ; }
return Read_Error ; // если тут 0, то все в порядке
}
catch( int E )
{
if( File_Error!=NULL )
{ fprintf( File_Error,"\n Файл %s не прочитан",File );
error_add( "t_Grammar :: make_all( " );
error_add( File );
error_add( " )\n" );
}
Fclose( File_Error );
Read_Error=-1 ;
return -1 ;
}
}
/***************************************************************************/
void t_Grammar :: del( void )
{
From.del() ;
To.del() ;
Format1.del() ;
File1.del() ;
Trans.del() ;
}
/***************************************************************************/
// прочесть из файла то, что можно прочесть
// File - имя файла lang.txt с путем
/***************************************************************************/
void t_Grammar :: read( char *File )
{
char *Mass, f_version=0 ;
long i,L ;
FILE *fr ;
try
{ fr=Fopen( File,"r" );
L=FileLength( fr );
Mass=(char *)Calloc( L,1 );
Fread( Mass,L,1,fr );
Fclose(fr);
Lexer.clr_breaker( );
Lexer.set_breaker( (uchar *)".,;:#$^=+-*/(){}<>[]\"\\." );
Lexer.init( Mass,L );
Lexer.make_words();
From.To=0 ;
To.To=1 ;
for( i=0 ; i<Lexer.n_word() ; i++ )
{
Ifstr( Lexer.Word[i],"@Версия")
{ if( 0!=strcmp(Lexer.Word[i+1],"00_00_00") )
{ fprintf( File_Error,"\n Не та версия lang.txt"); throw(-1); }
f_version=1 ;
}
Ifstr( Lexer.Word[i],"@Атомы_источника" )
i=From.read( &Lexer,i );
Ifstr( Lexer.Word[i],"@Атомы_приемника" )
i=To.read( &Lexer,i );
Ifstr( Lexer.Word[i],"@Словари_перевода" )
i=read_slowo1( i );
Ifstr( Lexer.Word[i],"@Переводы" )
i=read_trans( i );
}
Free( Mass );
if( f_version==0 )
{ fprintf( File_Error,"\n Отсутствует версия lang.txt"); throw(-1); }
}
catch( int E )
{
throw( E );
}
}
/***************************************************************************/
// прочесть словари переводов
// Begin - слово, с которого в lang.txt начинается описание словарей перевода
/***************************************************************************/
long t_Grammar :: read_slowo1( long Begin )
{ long i,i1,z,End,End1 ;
t_Format1 Form,*Form1 ;
t_File File2 ;
End=Lexer.find_paar( Begin,"{","}" );
for( i=Begin ; i<End ; i++ )
{ Ifstr( Lexer.Word[i],"@Формат_перевод" )
{ Format1.add( Form );
Form1=Format1.list+Format1.j-1 ;
i=read_format1( i,Form1 );
}
Ifstr( Lexer.Word[i],"@Файлы_переводов" )
{
File2.i_part=0 ;
z=find_format1( Lexer.Word[i+1] );
File2.i_format=z ;
File2.FileName.j=0 ;
End1=Lexer.find_paar( i+2,"{","}" );
for( i1=i+3 ; i1<End1 ; i1++ )
{ char *a ;
Ifstr( Lexer.Word[i1],"," ) continue ;
a=(char *)Calloc( strlen(Lexer.Word[i1])+1,1 ); // Memory Leak
strcpy( a, Lexer.Word[i1] );
File2.FileName.add( a );
}
File1.add( File2 );
}
}
return End ;
}
/**************************************************************************/
// прочесть запись типа @Формат_перевода { ... }
// Begin - слово, с которого начинсется
// Format - заполняемая структура
/**************************************************************************/
long t_Grammar :: read_format1( long Begin, t_Format1 *Format )
{ long i,i1,End,End1 ;
t_PartDsk PartDsk ;
strcpy( Format->Name, Lexer.Word[Begin+1] );
Ifstr( Lexer.Word[Begin+2],"{" )
{ End = Lexer.find_paar( Begin,"{","}" );
if( End<0 ) { fprintf( File_Error,"\n Ошибка непарности скобок"); throw(-1); }
}
else { fprintf( File_Error,"\n Ошибка формата"); throw(-1); }
for( i=Begin+3 ; i<End ; i++ )
{
Ifstr( Lexer.Word[i],"@Псевдоним" )
{ // ------------- строка переименование ------------
t_Rename Ren ;
strcpy( Ren.Reduce, Lexer.Word[i+1] ) ;
strcpy( Ren.Full , Lexer.Word[i+2] ) ;
Format->Rename.add( Ren );
i+=2 ;
continue ;
}
Ifstr( Lexer.Word[i],"@Части_речи_источника" )
{ End1 = Lexer.find_paar( i,"{","}" );
for( i1=i+2 ; i1<End1 ; i1+=3 )
{
strncpy( PartDsk.Tag ,Lexer.Word[i1],2 ) ;
strcpy( PartDsk.Name,Lexer.Word[i1+1] );
if( Lexer.Word[i1+2][0]!=';' )
{ fprintf( File_Error,"\n Ошибка формата"); throw(-1); }
Format->SouPart.add( PartDsk );
}
i=End1 ;
}
Ifstr( Lexer.Word[i],"@Части_речи_приемника" )
{ End1 = Lexer.find_paar( i,"{","}" );
for( i1=i+2 ; i1<End1 ; i1+=3 )
{
strncpy( PartDsk.Tag ,Lexer.Word[i1],2) ;
strcpy( PartDsk.Name,Lexer.Word[i1+1] );
if( Lexer.Word[i1+2][0]!=';' )
{ fprintf( File_Error,"\n Ошибка формата"); throw(-1); }
Format->DstPart.add( PartDsk );
}
}
}
return End1 ;
}
/***************************************************************************/
// прочесть массив переводов
// Begin - слово, с которого начинсется
/***************************************************************************/
long t_Grammar :: read_trans( long Begin )
{ long i,i1,End ;
End=Lexer.find_paar( Begin,"{","}" );
for( i=Begin ; i<End ; i++ )
{ Ifstr( Lexer.Word[i],"@Перевод" )
i=read_trans1( i );
}
copy_words();
make_index_struct() ;
for( i1=0 ; i1<Trans.j ; i1++ )
Trans[i1].make_order( ) ;
return i ;
}
/***************************************************************************/
// скопировать описание частей речи в массив переводов t_Grammar->Trans
/***************************************************************************/
void t_Grammar :: copy_words( void )
{ short i,i1,i2,j ;
char *m1,*m2 ;
t_Trans T,*TT ;
t_TransList Trans1 ;
// ----------- найти "незадействованные" структуры --------
m1=(char *)Calloc( From.Part.j,sizeof(char) );
m2=(char *)Calloc( To.Part.j,sizeof(char) );
for( i=0 ; i<Trans.j ; i++ )
{ i1=find_part( &From.Part, Trans[i].From.Name );
if( 0<=i1 )
{ if( m1[i1]!=0 )
{ fprintf( File_Error,"\n Многократный перевод атома %ld",
Trans[i].From.i_str );
Read_Error=-1 ;
}
m1[i1]=1 ;
}
i2=find_part( &To.Part, Trans[i].To.Name );
if( 0<=i2 )
{ if( m2[i2]!=0 )
{ fprintf( File_Error,"\n Многократный перевод атома %ld",
Trans[i].From.i_str );
Read_Error=-1 ;
}
m2[i2]=1 ;
}
}
// ----------- внести их в массив Trans1 -------------------
for( i=0 ; i<From.Part.j ; i++ )
if( m1[i]==0 )
{ Trans1.add( T );
TT=Trans1.list+Trans1.j-1 ;
TT->From =From.Part[i] ;
//TT->From.type=TSTRUCT1 ;
}
for( i=j=0 ; i<To.Part.j ; i++ )
if( m2[i]==0 )
{ if( Trans1.j<=j )
Trans1.add( T );
TT=Trans1.list+j ;
TT->To=To.Part[i] ;
//TT->To.type=TSTRUCT1 ;
j++ ;
}
for( i=0 ; i<Trans.j ; i++ )
{ i1=find_part( &From.Part, Trans[i].From.Name );
i2=find_part( &To.Part , Trans[i].To.Name );
if( 0<=i1 && 0<=i2 )
{ // ----- внести в массив Trans1 задействованные слова ------
Trans1.add( T );
TT=Trans1.list+Trans1.j-1 ;
TT->From=From.Part[i1] ;
TT->To =To.Part[i2] ;
}
if( i1<0 && i2<0 )
// ------- внести в массив Trans1 все остальное ---
Trans1.add( Trans[i] );
}
Trans.del();
Trans=Trans1 ;
Trans1.del();
Free(m1); Free(m2);
}
/***************************************************************************/
// чтение одной записи типа @Перевод
// Begin - слово, с которого начинсется
/***************************************************************************/
long t_Grammar :: read_trans1( long Begin )
{ t_Trans TT,*T ;
long i,end ;
char *pStr ;
char f ;
Trans.add(TT) ;
T=Trans.list+Trans.j-1 ;
end=Lexer.find_paar( Begin+1,"{","}" );
for( i=Begin+1,f=0 ; i<end ; i++ )
{ pStr=Lexer.Word[i] ;
if( 0==strcmp(pStr,"@Выбор") ||
0==strcmp(pStr,"@Выбор1") ||
0==strcmp(pStr,"@Выбор2") ||
0==strcmp(pStr,"@Структура") ||
0==strcmp(pStr,"@Структура1") ||
0==strcmp(pStr,"@Структура2") ||
0==strcmp(pStr,"@Множество") ||
0==strcmp(pStr,"@Беспорядок") ||
0==strcmp(pStr,"@Беспорядок1") ||
0==strcmp(pStr,"@Беспорядок2") )
{ if( f==0 ) { i=T->From.read( i,&From ); f++ ; }
if( f==1 ) { i=T->To.read ( i,&To ); f++ ; }
}
Ifstr( Lexer.Word[i],"@Таблица" )
i=read_table( i+1,T );
}
T->make_order( );
if( T->From.type!=T->To.type )
{ fprintf( File_Error,"\n Выбор и структура в одном переводе %ld",
Lexer.Str[Begin] );
Read_Error=-1 ;
}
return end ;
}
/***************************************************************************/
// чтение одной записи типа @Таблица
// Begin - слово, с которого начинсется
// TT - заполняемая пара
/***************************************************************************/
long t_Grammar :: read_table( long Begin, t_Trans *TT )
{ long i,j,i_param,End ;
short z ;
t_2Index I ;
char f,f1,*pStr ;
t_Table *T,T1 ;
TT->Table.add( T1 );
T=TT->Table.list+TT->Table.j-1 ;
End=Lexer.find_paar( Begin,"(",")" );
// ------------------- трансляция заголовка таблицы ----------------
for( f=f1=0,i=Begin+1 ; i<End ; i++ )
{ pStr=Lexer.Word[i] ;
Ifstr( pStr,"," ) { f1=0 ; continue ; }
Ifstr( pStr,"=" ) { f=1 ; f1=0 ; continue ; }
if( f1==0 )
{ f1++ ;
if( 0==strcmp("@Выбор",pStr) ) { i_param=-1 ; goto M_Found ; }
if( f==0 ) i_param=find_param( &From.Param,pStr );
else i_param=find_param( &To.Param ,pStr );
}
else
{
M_Found: f1++ ;
if( f==0 ) // --- найти параметр с таким именем в структуре источника--
{ I=TT->From.find_param2(pStr) ;
I.i_param=i_param ;
strcpy( I.Name,pStr );
T->In.add( I );
if( I.i1<0 ) Lexer.error( i );
}
else // --- найти параметр с таким именем в структуре приемника--
{ I=TT->To.find_param2(pStr) ;
I.i_param=i_param ;
strcpy( I.Name,pStr );
T->Out.add( I );
if( I.i1<0 ) Lexer.error( i );
}
}
}
T->Size=T->In.j+T->Out.j ;
if( T->In.j==0 || T->Out.j==0 )
{ fprintf( File_Error,"\n Заголовок таблицы - плохой строка %ld",
Lexer.Str[i] );
Read_Error=-1 ;
return End ;
}
// ------------------- трансляция тела таблицы ----------------
t_Param *P ;
Begin=End+1 ;
End=Lexer.find_paar( Begin,"{","}" );
j=0 ;
for( i=Begin+1 ; i<End ; i++ )
{ pStr=Lexer.Word[i] ;
Ifstr( pStr,";" ) { j=0 ; continue ; }
Ifstr( pStr,"=" ) { continue ; }
if( j<T->In.j ) // ---- значения до знака равно ---------
{ i_param=T->In[j].i_param ;
if( i_param<0 ) goto M_Select ;
P=&From.Param[i_param] ;
}
else // ---- значения после знака равно ---------
{ i_param=T->Out[j-T->In.j].i_param ;
if( i_param<0 ) goto M_Select ;
P=&To.Param[i_param] ;
}
z=find_value( &P->Value,pStr );
T->Value.add( z );
j++ ;
continue ;
// ----------- обработка параметра @Выбор --------
M_Select :
z=atoi(pStr);
T->Value.add( z );
j++ ;
}
return End ;
}
/***************************************************************************/
// приведение в порядок ссылок на структуры по их именам
/***************************************************************************/
void t_Grammar :: make_index_struct( void )
{ t_Trans *T ;
t_Word *W ;
long i,i1,z ;
char F_Error=0 ;
// ------ цикл по трансляционным парам -------------------
for( i=0 ; i<Trans.j ; i++ )
{ T=Trans.list+i ;
make_index_param0( i );
// ------ обработка структуры источника ---------------
for( i1=0 ; i1<T->From.Word.j ; i1++ )
{ W=T->From.Word.list+i1 ;
if( tst_const( W,T->From.i_str ) ) continue ;
z=find_struct( FROM, W->Name );
if( z<0 )
{ fprintf( File_Error,"\n Не могу найти структуру \n Строка %ld %s",
T->From.i_str,W->Name );
F_Error=1 ; continue ;
}
W->i_struct=z ;
W->type =Trans[z].From.type ;
make_index_param( FROM,i,i1 );
}
// ------ обработка структуры приемника ---------------
for( i1=0 ; i1<T->To.Word.j ; i1++ )
{ W=T->To.Word.list+i1 ;
if( tst_const( W,T->From.i_str ) ) continue ;
z=find_struct( TO, W->Name );
if( z<0 )
{ fprintf( File_Error,"\n Не могу найти структуру \n Строка %ld %s",
T->To.i_str,W->Name );
F_Error=1 ; continue ;
}
W->i_struct=z ;
W->type =Trans[z].To.type ;
make_index_param( TO,i,i1 );
}
}
if( F_Error==1 )
throw(-1) ;
}
/***************************************************************************/
// приведение в порядок ссылок на параметры слов по именам параметров
// i_trans - индекс трансляционной пары
/***************************************************************************/
void t_Grammar :: make_index_param0( long i_trans )
{ short i,i1 ;
t_Param1List *P ;
P=&Trans[i_trans].From.Param ;
for( i=0 ; i<P->j ; i++ )
{ i1=P->list[i].param ;
P->list[i].value=find_value( &From.Param[i1].Value,P->list[i].Name );
}
P=&Trans[i_trans].To.Param ;
for( i=0 ; i<P->j ; i++ )
{ i1=P->list[i].param ;
P->list[i].value=find_value( &To.Param[i1].Value,P->list[i].Name );
}
}
/***************************************************************************/
// приведение в порядок ссылок на параметры слов по именам параметров
// Half - источник или приемник
// i_trans - индекс трансляционной пары (он же индекс структуры)
// i_word - индекс подструктуры
/***************************************************************************/
void t_Grammar :: make_index_param( e_Half Half, long i_trans, long i_word )
{
long i,i1,i2,z,i_struct ;
char f ;
t_Param1List *p;
t_Struct *S;
t_Word *W ;
t_Lang *Lang ;
t_Form *F ;
t_Format *FF ;
if( Half==FROM ) S=&Trans[i_trans].From ;
else S=&Trans[i_trans].To ;
// --------- проверка на соответствие числа параметров -----------
if( Half==FROM )
{ W = &Trans[i_trans].From.Word[i_word] ;
i_struct=W->i_struct ;
p = &Trans[i_struct].From.Param ;
}
else
{ W = &Trans[i_trans].To.Word[i_word] ;
i_struct=W->i_struct ;
p = &Trans[i_struct].To.Param ;
}
if( W->Param.j!=p->j )
{ // --------------- Если не соответствует - печать об ошибке
fprintf( File_Error,"\n Не соответствие числа параметров \n Строка %ld %s->%s",
S->i_str,S->Name, W->Name );
Read_Error=-1 ;
}
else
{ // -------- а если все в порядке - проставить номера параметров
for( i=0 ; i<W->Param.j ; i++ )
{ W->Param[i].param=i1=p->list[i].param ;
if( W->Param[i].Name[0]=='%' )
{ if( Half==FROM ) z=find_value( &From.Param[i1].Value,W->Param[i].Name+1 );
else z=find_value( & To.Param[i1].Value,W->Param[i].Name+1 );
if( z<0 )
{
fprintf( File_Error,"\n Неизвесное значение параметра %s \n Строка %ld %s->%s",
W->Param[i].Name,S->i_str,S->Name, W->Name );
Read_Error=-1 ;
}
W->Param[i].value=z ;
}
else
W->Param[i].value=-1 ;
}
// ----------- проверка на допустимые комбинации параметров ----
if( W->Param.j==0 || W->type!=TWORD ) return ;
if( Half==FROM ) Lang=&From ; else Lang=&To ;
// ----------- проверка, что такую проверку надо проводить ----
for( i=0,f=0 ; i<Lang->Part[W->i_struct].Param.j ; i++ )
if( Lang->Part[W->i_struct].Param[i].Dir==0 )
f=1 ;
if( f==0 ) return ;
for( i=0 ; i<Lang->File.j ; i++ )
{ if( Lang->File[i].i_part!=W->i_struct ) continue ;
FF=&Lang->Format[ Lang->File[i].i_format ] ;
for( i1=0 ; i1<FF->Record.j ; i1++ )
{
F= &FF->Record[i1] ;
for( i2=0 ; i2<W->Param.j ; i2++ )
{ if( 0<=W->Param[i2].value && 0<=F->value[i2] &&
W->Param[i2].value!=F->value[i2] ) goto M_No;
}
return ; // нужная комбинация найдена
M_No:;
}
}
fprintf( File_Error,"\n невозможная комбинация параметров \n Строка %ld %s->%s",
S->i_str,S->Name, W->Name );
Read_Error=-1 ;
}
}
/***************************************************************************/
// установка индексов слов, структур, и т.д.
/***************************************************************************/
void t_Grammar :: make_index( void )
{ short i,i1 ;
t_Struct *S,*S1 ;
for( i=0 ; i<Trans.j ; i++ )
{ // ----- проверка на присутствие конструкций с одинаковыми именами ----
for( i1=0 ; i1<i ; i1++ )
{ S =&Trans[i].From ; S1=&Trans[i1].From ;
if( S->type==TNULL || S->type==TNULL ) continue ;
if( 0==strcmp( S->Name,S1->Name ) )
{ fprintf( File_Error,"\n Конструкция %s описана два раза\n Строки %ld и %ld",
S->Name, S->i_str,S1->i_str );
Read_Error=-1 ;
}
S =&Trans[i].To ; S1=&Trans[i1].To ;
if( 0==strcmp( S->Name,S1->Name ) )
{ fprintf( File_Error,"\n Конструкция %s описана два раза\n Строки %ld и %ld",
S->Name, S->i_str,S1->i_str );
Read_Error=-1 ;
}
}
// ------ собственно расстановка индексов -------------------
S=&Trans[i].From ;
for( i1=0 ; i1<S->Word.j ; i1++ )
index_word( &S->Word[i1], FROM );
S=&Trans[i].To ;
for( i1=0 ; i1<S->Word.j ; i1++ )
index_word( &S->Word[i1], TO );
Trans[i].make_index_table( );
Trans[i].From.trans_relation( );
Trans[i].To.trans_relation( );
Trans[i].make_order();
Trans[i].From.tst_relation( );
Trans[i].To.tst_relation( );
}
}
/***************************************************************************/
// проставить индексы структур словам
/***************************************************************************/
void t_Grammar :: index_word( t_Word *W, e_Half Half )
{
if( W->type!=TWORD && W->type!=TCONST && W->type!=TCONST1 && W->type!=TWORD0 )
{ W->i_struct = find_struct( Half, W->Name );
W->type = Trans[W->i_struct].From.type ;
}
}
/**************************************************************************/
// узнать номер структуры по ее имени
/**************************************************************************/
short t_Grammar :: find_struct( e_Half Half, char *Name )
{
if( Half==FROM )
{ for( short i=0 ; i<Trans.j ; i++ )
if( 0==strcmp( Trans.list[i].From.Name,Name) ) return i ;
}
else
{ for( short i=0 ; i<Trans.j ; i++ )
if( 0==strcmp( Trans.list[i].To.Name,Name) ) return i ;
}
return -1 ;
}
/**************************************************************************/
// узнать номер формата перевода по его имени
/**************************************************************************/
short t_Grammar :: find_format1( char *Name )
{
for( short i=0 ; i<Format1.j ; i++ )
if( 0==strcmp( Format1[i].Name,Name ) ) return i ;
return -1 ;
}
/**************************************************************************/
t_Trans& t_Grammar :: operator []( long i )
{ if( i<0 || Trans.j<=i )
{ printf("\n Error index grammar");
error_set("Error index grammar!!!");
throw(-1);
}
return Trans.list[i];
}
/**************************************************************************/
short t_Grammar :: n_trans( void )
{ return Trans.j ; }
/**************************************************************************/
short t_Grammar :: main_struct( void )
{ return Trans.j-1 ; }
/**************************************************************************/
short t_Grammar :: i_number( void )
{ return i_Number ; }
/**************************************************************************/
t_Lang& t_Grammar :: from( void )
{ return From ; }
/**************************************************************************/
t_Lang& t_Grammar :: to( void )
{ return To ; }
/**************************************************************************/
t_Format1List& t_Grammar :: format1( void )
{ return Format1 ; }
/**************************************************************************/
t_FileList& t_Grammar :: file1( void )
{ return File1 ; }
/***************************************************************************/
// создание таблицы передачи параметров для t_Trans
/***************************************************************************/
void t_Trans :: make_index_table( void )
{ short i,i1 ;
t_Table *T ;
t_2Index I ;
for( i=0 ; i<Table.j ; i++ )
{ T=&Table[i] ;
for( i1=0 ; i1<T->In.j ; i1++ )
{ I=From.find_param2(T->In[i1].Name) ;
T->In[i1].i1=I.i1 ;
T->In[i1].i2=I.i2 ;
}
for( i1=0 ; i1<T->Out.j ; i1++ )
{ I=To.find_param2(T->Out[i1].Name) ;
T->Out[i1].i1=I.i1 ;
T->Out[i1].i2=I.i2 ;
}
}
}
/***************************************************************************/
// задание соответствия между составляющими источника и приемника
/***************************************************************************/
void t_Trans :: make_order( void )
{
short is1,is2,n_relation ;
long i,i1 ;
for( i=0 ; i<To.Word.j ; i++ )
To.Word[i].use=0 ;
is1=-1 ;
Relation1.j=Relation2.j=0 ;
for( i=0 ; i<From.Word.j ; i++ )
Relation1.add( is1 );
for( i=0 ; i<To.Word.j ; i++ )
Relation2.add( is1 );
// --------------- формирование Relation1 -----------------------
for( i=0 ; i<From.Word.j ; i++ )
{
if( From.Word[i].order<0 )
{ // -------------- неявное задание порядка --------------
is1=From.Word[i].i_struct ;
n_relation=0 ;
for( i1=0 ; i1<To.Word.j ; i1++ )
{ if( 0<=To.Word[i1].order || To.Word[i1].use!=0 ) continue ;
is2=To.Word[i1].i_struct ;
if( is1==is2 )
{ Relation1[i] =i1 ;
Relation2[i1]=i ;
To.Word[i1].use=1 ;
n_relation++ ;
break ;
}
}
if( To.Word.j<n_relation )
{ fprintf( File_Error,"\n ошибка соответствия структур %s %s",
From.Name,To.Name );
Read_Error=-1 ;
throw(-1);
}
}
else
{ // -------------- явное задание порядка --------------
for( i1=0 ; i1<To.Word.j ; i1++ )
{ if( To.Word[i1].order<0 ) continue ;
if( From.Word[i].order==To.Word[i1].order )
{ if( From.Word[i].i_struct!=To.Word[i1].i_struct )
{ fprintf( File_Error,"\n %s ошибка соответствия структур2",From.Name );
Read_Error=-1 ;
throw(-1);
}
Relation1[i]=i1;
Relation2[i1]=i;
}
}
}
}
// ----- если это выбор, проверить его варианты на соответствие -----
if( From.type==TSELECT || From.type==TSELECT2 )
{
if( From.Word.j!=To.Word.j )
{ fprintf( File_Error,"\n %s : несоответствие числа вариантов выбора",From.Name );
Read_Error=-1 ;
}
for( i=0 ; i<From.Word.j ; i++ )
if( From.Word[i].i_struct!=To.Word[i].i_struct &&
0<=From.Word[i].i_struct && 0<=To.Word[i].i_struct )
{ fprintf( File_Error,"\n %s->%s : несоответствие вариантов выбора",
From.Name,From.Word[i].Name );
Read_Error=-1 ;
}
}
}
/***************************************************************************/
// прочесть запись типа @Структура @Выбор
// Begin - слово, с которого начинсется
// Lang - язык, к которому относится эта структура
/***************************************************************************/
long t_Struct :: read( long Begin, t_Lang *Lang )
{
t_Word W ;
char *pStr ;
long i,i1,end,End ;
End=Lexer.n_Word ;
for( i=Begin ; i<End ; i++ )
{
pStr=Lexer.Word[i] ;
if( 0==strcmp(pStr,"@Часть_речи") ||
0==strcmp(pStr,"@Структура") ||
0==strcmp(pStr,"@Структура1") ||
0==strcmp(pStr,"@Структура2") ||
0==strcmp(pStr,"@Выбор") ||
0==strcmp(pStr,"@Выбор1") ||
0==strcmp(pStr,"@Выбор2") ||
0==strcmp(pStr,"@Множество") ||
0==strcmp(pStr,"@Беспорядок") ||
0==strcmp(pStr,"@Беспорядок1") ||
0==strcmp(pStr,"@Беспорядок2") )
{
if( 40<=strlen(Lexer.word(i+1)) )
{ fprintf( File_Error,"\n Слишком длинное имя структуры %s",Lexer.word(i+1) );
throw(-1);
}
strcpy( Name,Lexer.word(i+1) );
Ifstr( pStr,"@Часть_речи" ) type=TWORD ;
Ifstr( pStr,"@Структура" ) type=TSTRUCT ;
Ifstr( pStr,"@Структура1" ) type=TSTRUCT1 ;
Ifstr( pStr,"@Структура2" ) type=TSTRUCT2 ;
Ifstr( pStr,"@Выбор" ) type=TSELECT ;
Ifstr( pStr,"@Выбор1" ) type=TSELECT1 ;
Ifstr( pStr,"@Выбор2" ) type=TSELECT2 ;
Ifstr( pStr,"@Множество" ) type=TENUM ;
Ifstr( pStr,"@Беспорядок" ) type=TUNORDER ;
Ifstr( pStr,"@Беспорядок1") type=TUNORDER1 ;
Ifstr( pStr,"@Беспорядок2") type=TUNORDER2 ;
i_str=Lexer.Str[i+1] ;
// -------------- трансляция параметров ----------------- //
i=trans_param( i, Lang );
if( type != TWORD && 0!=strcmp( Lexer.Word[i],"=" ) )
{ fprintf( File_Error,"\n В строке %s нет знака равно",Name );
throw(-1);
}
// ----------- трансляция составляющих ----------------
end=Lexer.find_word( i,";" );
for( i1=i+1 ; i1<end ; i1++ )
i=i1=trans_word1( i1 );
return i+1 ;
}
}
return i ; //End ;
}
/***************************************************************************/
// трансляция составляющих структуры или варианта выбора
// Begin - слово, с которого начинсется
/***************************************************************************/
long t_Struct :: trans_word1( long Begin )
{ long i ;
t_Word W ;
char use,*pStr ;
for( i=Begin ; i<Lexer.n_word() ; i++ )
{
Ifstr( Lexer.Word[i],";" ) { return i+1 ; }
zerstoren_word( Lexer.Word[i], &use, &pStr );
strcpy( W.Name,pStr );
W.meaning_use=use ;
i=trans_order( i,&W );
Word.add( W );
return trans_word( i );
}
return Lexer.n_word();
}
/***************************************************************************/
// Трансляция вот таких фенечек @Структура = часть<1> часть<2>
// Begin - слово, с которого начинсется ^^^ ^^^
// Word1 - часть структуры, которой проставляется order
/***************************************************************************/
long t_Struct :: trans_order( long Begin, t_Word *Word1 )
{ long i=Begin ;
Ifstr( Lexer.Word[i+1],"<" )
{ Ifstr( Lexer.Word[i+3],">" )
Word1->order=atoi( Lexer.Word[i+2] );
else Lexer.error(i);
i+=3 ;
}
Ifstr( Lexer.Word[i+1],"[" )
{ Ifstr( Lexer.Word[i+3],"]" )
strcpy( Word1->literal, Lexer.Word[i+2] );
else
{ fprintf( File_Error,"\n В строке %ld пустая константа",Lexer.Str[i+2] );
Read_Error=-1 ;
}
i+=3 ;
}
return i ;
}
/***************************************************************************/
// трансляция параметров структуры
// Begin - слово, с которого начинсется
// Lang - язык, к которому относится эта структура
/***************************************************************************/
long t_Struct :: trans_param( long Begin, t_Lang *Lang )
{ t_Param1 Param1 ;
long i,z,End ;
char *pStr ;
Ifstr( Lexer.word(Begin+2),"(" )
{ // -------------- если у структуры есть параметры -----------
End=Lexer.find_paar( Begin+2,"(",")" );
for( i=Begin+3 ; i<End ; i++ )
{ char d ;
Ifstr( Lexer.Word[i],"," ) continue ;
z=find_param( &Lang->Param,Lexer.Word[i] );
if( z<0 ) continue ;
Param1.param=z ;
pStr=Lexer.Word[i+1] ;
zerstoren_param( Lexer.Word[i+1], &d, &pStr );
strcpy( Param1.Name,pStr );
Param1.Dir=d ;
Param.add( Param1 ); i++ ;
}
return End+1 ;
}
else
{ // --------------- и если параметров нет -----------------
return Begin+2 ;
}
}
/***************************************************************************/
// трансляция параметров части структуры
// Begin - слово, с которого начинсется
/***************************************************************************/
long t_Struct :: trans_word( long Begin )
{
t_Param1 Param1 ;
t_Word *W=&Word[Word.j-1] ;
long i,End ;
char Dir,*Str ;
Ifstr( Lexer.Word[Begin+1],"(" )
End=Lexer.find_paar( Begin+1,"(",")" );
else End=Begin ;
for( i=Begin+2 ; i<End ; i++ )
{
Ifstr( Lexer.Word[i],"," ) continue ;
zerstoren_param( Lexer.Word[i],&Dir,&Str );
Param1.param=-1 ;
Param1.Dir=Dir ;
strcpy( Param1.Name,Str );
Param1.value=-1 ;
W->Param.add( Param1 );
}
return End ;
}
/**************************************************************************/
// сформировать описание передачи параметров внутри конструкции
// одного языка (Relation)
/**************************************************************************/
void t_Struct :: trans_relation( void )
{ t_Param1 *Param1 ;
t_Relation *Index,I ;
short *gruppe ;
long i,i1,j,N ;
if( type==TWORD ) return ;
N=Param.j ;
for( i=0 ; i<Word.j ; i++ )
N+=Word[i].Param.j ;
Param1=(t_Param1 *)Calloc( N,sizeof(t_Param1 ) );
Index =(t_Relation *)Calloc( N,sizeof(t_Relation) );
gruppe=(short *)Calloc( N,sizeof(short) );
// ----------- инициация массивов структуры -------------
for( i=j=0 ; i<Param.j ; i++ )
{ if( 0<=Param[i].value ) continue ;
Param1[j]=Param[i] ;
Index[j].s1=Index[i].s2=0 ;
Index[j].p1=Index[i].p2=i ;
gruppe[j]=j ;
j++ ;
}
// ----------- инициация массивов составляющих -------------
for( i=0 ; i<Word.j ; i++ )
{ for( i1=0 ; i1<Word[i].Param.j ; i1++ )
{ if( 0<=Word[i].Param[i1].value ) continue ;
Param1[j]=Word[i].Param[i1] ;
Index[j].s1=Index[j].s2=i+1 ;
Index[j].p1=Index[j].p2=i1 ;
gruppe[j]=j ;
j++ ;
}
}
N=j ;
// ----------- заполнение массивов Relation ----------------
for( i=0 ; i<N ; i++ )
{
for( i1=i ; i1<N ; i1++ )
if( 0==strcmp(Param1[i].Name,Param1[i1].Name) )
{ gruppe[i1]=i ;
if( Param1[i].Dir==1 && Param1[i1].Dir==0 )
{ I.s1=Index[i].s1 ; I.s2=Index[i1].s1 ;
I.p1=Index[i].p1 ; I.p2=Index[i1].p1 ;
Relation.add( I );
}
if( Param1[i].Dir==0 && Param1[i1].Dir==1 )
{ I.s1=Index[i1].s1 ; I.s2=Index[i].s1 ;
I.p1=Index[i1].p1 ; I.p2=Index[i].p1 ;
Relation.add( I );
}
}
}
Free( Param1 ); Free( Index ); Free( gruppe );
}
/**************************************************************************/
// найти в структуре положение ( индекс слова и индекс параметра )
// параметра источника с именем Str
/**************************************************************************/
t_2Index t_Struct :: find_param2( char *Str )
{ t_2Index r ;
t_Param1List *P ;
short i,i1 ;
if( 0==strcmp("@Выбор",Str) ) { r.i1=0 ; r.i2=-1 ; return r ; }
P=&Param ;
// ------- поиск в заголовке структуры -------------
for( i=0 ; i<P->j ; i++ )
{ if( P->list[i].Dir==0 && type==TSTRUCT ) continue ;
if( 0==strcmp(P->list[i].Name,Str) )
{ r.i1=0 ; r.i2=i ; return r ; }
}
// ------- поиск в составляющих структуры ----------
for( i1=0 ; i1<Word.j ; i1++ )
{ P=&Word[i1].Param ;
for( i=0 ; i<P->j ; i++ )
{ if( P->list[i].Dir==0 ) continue ;
if( 0==strcmp(P->list[i].Name,Str) )
{ r.i1=i1+1 ; r.i2=i ; return r ; }
}
}
fprintf( File_Error,"\n %ld В структуре не могу найти параметр \"%s\"",i_str,Str );
Read_Error=-1 ;
r.i1=-1 ; r.i2=-1 ; return r ;
}
/**************************************************************************/
// проверка параметров на соответствие типов при прямой передаче
/**************************************************************************/
void t_Struct :: tst_relation( void )
{ long i ;
t_Relation I ;
t_Param1List *P1,*P2 ;
for( i=0 ; i<Relation.j ; i++ )
{ I=Relation[i] ;
if( I.s1==0 ) P1=&Param ;
else P1=&Word[I.s1-1].Param ;
if( I.s2==0 ) P2=&Param ;
else P2=&Word[I.s2-1].Param ;
if( P1->list[I.p1].param!=P2->list[I.p2].param )
{ fprintf( File_Error,"\n Прямая передача значений между разнородными параметрами");
fprintf( File_Error,"\n Строка = %ld структура = %s параметр = %s",
i_str, Name, P1->list[I.p1].Name ) ;
Read_Error=-1 ;
}
}
}
/***************************************************************************/
// прочесть запись типа @Атомы_источника{ ... } или @Атомы_приемника{ ... }
// Lexer - Лексер, который содержит lang.txt
// Begin - слово, с которого начинается
/***************************************************************************/
long t_Lang :: read( t_Lexer *_Lexer, long Begin )
{
long i,i1,End,End1 ;
t_Value Value1 ;
t_Param Param1 ;
t_Struct Part1 ;
t_Format Form,*Form1 ;
t_File File1 ;
short z ;
try
{
Lexer=_Lexer ;
Ifstr( Lexer->Word[Begin+1],"{" )
{ End = Lexer->find_paar( Begin,"{","}" );
if( End<0 ){ fprintf(File_Error,"\n Ошибка непарности скобок"); throw(-1); }
}
else { fprintf(File_Error,"\n Ошибка формата"); throw(-1); }
for( i=Begin+1 ; i<End ; i++ )
{
Ifstr( Lexer->Word[i],"@Параметр" )
{ strcpy( Param1.Name,Lexer->Word[i+1]) ;
Param.add( Param1 );
t_Param *P=&Param[Param.j-1] ;
End1=Lexer->find_paar( i+2,"{","}" );
for( i1=i+3 ; i1<End1 ; i1++ )
{ Ifstr( Lexer->Word[i1],"," ) continue ;
strcpy( Value1.Name,Lexer->Word[i1] );
P->Value.add( Value1 );
}
}
if( 0==strcmp( Lexer->Word[i],"@Часть_речи" ) ||
0==strcmp( Lexer->Word[i],"@Структура" ) ||
0==strcmp( Lexer->Word[i],"@Структура1" ) ||
0==strcmp( Lexer->Word[i],"@Структура2" ) ||
0==strcmp( Lexer->Word[i],"@Множество" ) ||
0==strcmp( Lexer->Word[i],"@Беспорядок" ) ||
0==strcmp( Lexer->Word[i],"@Беспорядок1" ) ||
0==strcmp( Lexer->Word[i],"@Беспорядок2" ) )
{
Part.add( Part1 );
Part[Part.j-1].read( i,this );
}
Ifstr( Lexer->Word[i],"@Формат" )
{ Format.add( Form );
Form1=&Format[Format.j-1] ;
read_format( i, Form1 );
}
Ifstr( Lexer->Word[i],"@Файлы" )
{
z=find_part( &Part,Lexer->Word[i+1] );
File1.i_part=z ;
z=find_format( &Format,Lexer->Word[i+2] );
File1.i_format=z ;
File1.FileName.j=0 ;
End1=Lexer->find_paar( i+3,"{","}" );
for( i1=i+4 ; i1<End1 ; i1++ )
{ char *a ;
Ifstr( Lexer->Word[i1],"," ) continue ;
a=(char *)Calloc( strlen(Lexer->Word[i1])+1,1 ); // Memory Leak
strcpy( a,Lexer->Word[i1] );
File1.FileName.add( a );
}
File.add( File1 );
}
}
return End ;
}
catch( int E )
{
throw( E );
}
}
/**************************************************************************/
// прочесть запись типа @Формат { ... }
// Begin - слово, с которого начинается
// Format1 - то, что надо заполнить
/**************************************************************************/
void t_Lang :: read_format( long Begin, t_Format *Format1 )
{
long i,i1,s,z,z1,z2 ;
long End ;
t_Struct *P ;
t_Form Form[10] ;
for( i=0 ; i<10 ; i++ ) Form[i].init() ;
z=find_part( &Part,Lexer->Word[Begin+1] );
if( z<0 ) { fprintf( File_Error,"\n Ошибка поиска части речи" ); throw(-1); }
Format1->i_part=z ;
P=&Part[z] ;
strcpy( Format1->Name, Lexer->Word[Begin+2] );
Ifstr( Lexer->Word[Begin+3],"{" )
{ End = Lexer->find_paar( Begin,"{","}" );
if( End<0 ) { fprintf( File_Error,"\n Ошибка непарности скобок"); throw(-1); }
}
else { fprintf( File_Error,"\n Ошибка формата"); throw(-1); }
s=0 ;
for( i=Begin+3 ; i<End ; i++ )
{
Ifstr( Lexer->Word[i],"{" ) { Form[s+1]=Form[s] ; s++ ; continue ; }
Ifstr( Lexer->Word[i],"}" ) { s-- ; continue ; }
Ifstr( Lexer->Word[i],"@Слово" )
{
Format1->Record.add( Form[s] );
continue ;
}
for( i1=0 ; i1<P->Param.j ; i1++ )
if( 0==strcmp(P->Param[i1].Name,Lexer->Word[i]) )
{ z1=i1 ; z=P->Param[i1].param ; goto M_Ok ; }
fprintf( File_Error,"\n Часть речи (%s) не имеет параметра(%s)",
P->Name,Lexer->Word[i] );
Read_Error=-1 ;
M_Ok:;
Ifstr( Lexer->Word[i+1],"=" )
{ // -------------- найти значение параметра -------------
z2=find_value( &Param[z].Value,Lexer->Word[i+2] );
if( z2<0 )
{ fprintf( File_Error,"\n Параметр(%s) не имеет значения(%s)",
Param[z].Name,Lexer->Word[i+2] );
throw(-1);
}
Form[s].value[z1]=z2 ;
i+=2 ;
}
}
}
/***************************************************************************/
// сделать индексы сруктур в списке переименований структур
/***************************************************************************/
void t_Format1 :: make_part( t_Grammar *Grammar )
{ short i,z ;
for( i=0 ; i<SouPart.j ; i++ )
{ z=Grammar->find_struct( FROM, SouPart[i].Name );
if( z<0 )
{ fprintf( File_Error,"\n @Словари_перевода :: не могу найти часть речи %s",
SouPart[i].Name );
Read_Error=-1 ;
}
SouPart[i].i_part = z ;
}
for( i=0 ; i<DstPart.j ; i++ )
{ z=Grammar->find_struct( TO, DstPart[i].Name );
if( z<0 )
{ fprintf( File_Error,"\n @Словари_перевода :: не могу найти часть речи %s",
DstPart[i].Name );
Read_Error=-1 ;
}
DstPart[i].i_part = z ;
}
}
/***************************************************************************/
// найти индекс структуры по ее псевдониму
// fTo - 0-источник или 1-приемник
// Tag - псевдоним
/***************************************************************************/
short t_Format1 :: find_struct( char fTo, char *Tag )
{ short i ;
if( Tag[0]=='@' && Tag[1]=='0' )
return -1 ; // если это константа
if( fTo==0 )
{ for( i=0 ; i<SouPart.j ; i++ )
if( 0==strncmp(Tag,SouPart.list[i].Tag,2) )
return SouPart.list[i].i_part ;
}
else
{ for( i=0 ; i<DstPart.j ; i++ )
if( 0==strncmp(Tag,DstPart.list[i].Tag,2) )
return DstPart.list[i].i_part ;
}
return -10 ; // структура не найдена
}
/**************************************************************************/
// дать псевдоним структуры по ее индексу
// fTo - 0-источник или 1-приемник
// i_struct - индекс структуры
/**************************************************************************/
char
* t_Format1 ::get_tag( char fTo, short i_struct )
{ static char Str[3] ;
short i ;
strcpy( Str,"@1" );
if( fTo==0 )
{ for( i=0 ; i<SouPart.j ; i++ )
if( SouPart.list[i].i_part==i_struct )
{ strncpy( Str,SouPart.list[i].Tag,2 ); break ; }
}
else
{ for( i=0 ; i<DstPart.j ; i++ )
if( DstPart.list[i].i_part==i_struct )
{ strncpy( Str,DstPart.list[i].Tag,2 ); break ; }
}
return Str ;
}
/**************************************************************************/
// дать имя структуры по ее индексу
// fTo - 0-источник или 1-приемник
// i_struct - индекс структуры
/**************************************************************************/
char
* t_Format1 ::get_name( char fTo, short i_struct )
{ short i ;
if( fTo==0 )
{ for( i=0 ; i<SouPart.j ; i++ )
if( SouPart.list[i].i_part==i_struct )
return SouPart.list[i].Name ;
}
else
{ for( i=0 ; i<DstPart.j ; i++ )
if( DstPart.list[i].i_part==i_struct )
return DstPart.list[i].Name ;
}
return "@0" ;
}
/**************************************************************************/
void t_Lang :: del( void )
{
Param.del( );
Part.del( );
Format.del( );
File.del( );
}
/***************************************************************************/
// проверка на то, что часть структуры является "жесткой константой"
// W - проверяемая часть структуры (Слово)
// i_str - индекс строки файла lang.txt, в которой это "Слово" записано
/***************************************************************************/
char tst_const( t_Word *W, long i_str )
{
Ifstr( "@0",W->Name )
{ W->i_struct=-1 ;
W->type =TCONST ;
if( W->literal[0]==0 )
{ fprintf( File_Error,"\n У константы нет значения \n Строка %ld %s",
i_str,W->Name );
throw(-1);
}
if( 0<W->Param.j ) goto M_ErrParam ;
return 1 ;
}
Ifstr( "@1",W->Name )
{ W->i_struct=-1 ;
W->type =TCONST1 ;
if( 0<W->Param.j ) goto M_ErrParam ;
return 1 ;
}
Ifstr( "@00",W->Name )
{ W->i_struct=-2 ;
W->type =TWORD0 ;
if( 0<W->Param.j ) goto M_ErrParam ;
return 1 ;
}
return 0 ;
M_ErrParam:
fprintf( File_Error,"\n У константы какие-то параметры \n Строка %ld %s",
i_str,W->Name );
throw(-1);
}
/**************************************************************************/
short find_param( t_ParamList *List, char *Str )
{
for( short i=0 ; i<List->j ; i++ )
if( 0==strcmp(List->list[i].Name,Str) ) return i ;
return -1 ;
}
/**************************************************************************/
short find_part( t_StructList *List, char *Str )
{
for( short i=0 ; i<List->j ; i++ )
if( 0==strcmp(List->list[i].Name,Str) ) return i ;
return -1 ;
}
/**************************************************************************/
short find_format(t_FormatList *List, char *Str )
{
for( short i=0 ; i<List->j ; i++ )
if( 0==strcmp(List->list[i].Name,Str) ) return i ;
return -1 ;
}
/**************************************************************************/
short find_value( t_ValueList *List, char *Str )
{
if( 0==strcmp( "@0",Str ) ) return -1 ;
for( short i=0 ; i<List->j ; i++ )
if( 0==strcmp(List->list[i].Name,Str) ) return i ;
return -1 ;
}
/***************************************************************************/
t_Form :: t_Form( void )
{
for( short i=9 ; 0<=i ; i-- ) value[i]=-1 ;
}
/***************************************************************************/
void t_Form :: init(void)
{
for( short i=9 ; 0<=i ; i-- ) value[i]=-1 ;
}
/***************************************************************************/
void t_Format1 :: init( void )
{
Name[0]=0 ;
SouPart.init();
DstPart.init();
}
/***************************************************************************/
void t_Format1 :: del( void )
{
SouPart.del();
DstPart.del();
}
/***************************************************************************/
t_Param :: t_Param( void ){ init();
}
t_Param :: ~t_Param( void ){ del(); }
void t_Param :: init( void )
{ Name[0]=0 ;
Value.init();
}
void t_Param :: del( void )
{ Value.del();
}
/***************************************************************************/
t_Format :: t_Format( void ){ init();
}
t_Format :: ~t_Format( void ){ del(); }
void t_Format :: init( void )
{
Name[0]=0 ;
i_part =0 ;
Record.init() ;
}
void t_Format :: del( void )
{
Record.del() ;
}
/***************************************************************************/
t_File :: t_File( void ){ init();
}
t_File :: ~t_File( void ){ del(); }
void t_File :: init( void )
{ i_part =0 ;
i_format=0 ;
FileName.init();
}
void t_File :: del( void )
{ // по идее надо освобождать и строки по этим адресам
FileName.del();
}
/**************************************************************************/
void t_Table :: init( void )
{ Size=0 ;
In.init();
Out.init();
Value.init();
}
/**************************************************************************/
void t_Table :: del( void )
{ In.del();
Out.del();
Value.del();
}
/**************************************************************************/
void t_Table :: operator = ( t_Table &T )
{ Size =T.Size ;
In =T.In ;
Out =T.Out ;
Value=T.Value ;
}
/**************************************************************************/
t_Word :: t_Word( void )
{
init( );
}
/**************************************************************************/
void t_Word :: init( void )
{
literal[0] = 0 ;
type = TWORD ;
Param.init();
order =-1 ;
i_struct =-1 ;
meaning_use= 0 ;
}
/**************************************************************************/
void t_Word :: del( void )
{
Param.del();
}
/**************************************************************************/
void t_Word :: operator = ( t_Word &W )
{
strcpy( literal,W.literal ) ;
strcpy( Name ,W.Name ) ;
type = W.type ;
Param = W.Param ;
order = W.order ;
i_struct = W.i_struct ;
use = W.use ;
meaning_use = W.meaning_use ;
}
/**************************************************************************/
t_Struct :: t_Struct( void )
{
init( );
}
/**************************************************************************/
void t_Struct :: init( void )
{
type =TNULL ;
Name[0] =0 ;
i_str =-1 ;
Word.init();
Param.init();
Relation.init();
}
/**************************************************************************/
void t_Struct :: del( void )
{
Word.del();
Param.del();
Relation.del();
}
/**************************************************************************/
void t_Struct :: operator = ( t_Struct &S )
{
strcpy( Name,S.Name );
type = S.type;
i_str = S.i_str;
Param = S.Param;
Word = S.Word;
Relation= S.Relation;
}
/**************************************************************************/
t_Trans :: t_Trans( void )
{ init( ); }
/**************************************************************************/
void t_Trans :: init( void )
{
From.init();
To.init();
Relation1.init();
Relation2.init();
Param1.init();
Param2.init();
Table.init();
}
/**************************************************************************/
void t_Trans :: del( void )
{
From.del();
To.del();
Relation1.del();
Relation2.del();
Param1.del();
Param2.del();
Table.del();
}
/**************************************************************************/
void t_Trans :: operator = ( t_Trans &SS )
{ short i ;
t_Struct *F,*T ;
F =&SS.From ;
T =&SS.To ;
From.Param=F->Param ;
To.Param =T->Param ;
// ------------ копирование слов источника -----------
for( i=0 ; i<F->Word.j ; i++ )
From.Word.add( F->Word[i] );
// ------------ копирование слов приемника -----------
for( i=0 ; i<T->Word.j ; i++ )
To.Word.add( T->Word[i] );
// ------------ копирование параметров и таблиц ------
Relation1 = SS.Relation1 ;
Relation2 = SS.Relation2 ;
Param1 = SS.Param1 ;
Param2 = SS.Param2 ;
Table = SS.Table ;
From.type = F->type ;
From.i_str= F->i_str ;
To.type = T->type ;
To.i_str = T->i_str ;
strcpy( From.Name,F->Name );
strcpy( To.Name, T->Name );
}
/**************************************************************************/
short find_param1( t_Param1List *List, char *Str )
{
for( short i=0 ; i<List->j ; i++ )
if( 0==strcmp(List->list[i].Name,Str) ) return i ;
return -1 ;
}
/**************************************************************************/
short find_value2( t_strList *List, char *Str )
{
if( 0==strcmp( "@0",Str ) ) return -1 ;
for( short i=0 ; i<List->j ; i++ )
if( 0==strcmp(List->list[i],Str) ) return i ;
return -1 ;
}
/**************************************************************************/
void zerstoren_param( char *Str, char *Dir, char **Str1 )
{
if( Str[0]=='&' ) { *Dir=1 ; *Str1=Str+1 ; }
else { *Dir=0 ; *Str1=Str ; }
}
/**************************************************************************/
void zerstoren_word( char *Str, char *use, char **Str1 )
{
if( Str[0]=='!' ) { *use=1 ; *Str1=Str+1 ; }
else { *use=0 ; *Str1=Str ; }
}
/**************************************************************************/
DEFINE_LIST_TYPE ( t_Trans, t_TransList )
DEFINE_LIST_TYPE ( t_Table, t_TableList )
DEFINE_LIST_BTYPE( t_Param1, t_Param1List )
DEFINE_LIST_BTYPE( t_2Index, t_2IndexList )
DEFINE_LIST_TYPE ( t_Word, t_WordList )
DEFINE_LIST_TYPE ( t_Struct, t_StructList )
DEFINE_LIST_BTYPE( t_Relation,t_RelationList )
DEFINE_LIST_BTYPE( t_PartDsk, t_PartDskList )
DEFINE_LIST_TYPE ( t_Format1, t_Format1List )
DEFINE_LIST_BTYPE( short, t_shortList )
DEFINE_LIST_BTYPE( long, t_longList )
DEFINE_LIST_BTYPE( t_Value, t_ValueList )
DEFINE_LIST_TYPE ( t_Param, t_ParamList )
DEFINE_LIST_TYPE ( t_Format, t_FormatList )
DEFINE_LIST_BTYPE( char *, t_strList )
DEFINE_LIST_TYPE ( t_File, t_FileList )
DEFINE_LIST_BTYPE( t_Rename, t_RenameList )
DEFINE_LIST_BTYPE( t_Form, t_FormList )