Улучшенный вариант добавлена оьработка комментариев типа (* *) и можно добавить еще операторов кроме begin record до 10 шт (лишь бы заканчивались end-ом просто не очень знаком с паскалем)
Код |
#include<ctype.h> #include<conio.h>
#include<stdio.h> #include<string.h>
#include<io.h>
#include<stdlib.h>
//Препроцессор при компилировании посчитает размер массива структур #define N (sizeof(ident_acess) / sizeof(ident_acess[ 0 ]))
//благодаря этому участку кода мы далее обращаемся к любомк элементу //структуры так сказать без проблем #define NON -1 #define DELIMITERS FNDelm( "DELIMITERS" ) #define COMMENT1 FNDelm( "COMMENT1" ) #define COMMENT2 FNDelm( "COMMENT2" ) #define COMMENT3 FNDelm( "COMMENT3" ) #define TEXT FNDelm( "TEXT" ) #define BLOCK FNDelm( "BLOCK" ) #define MAXSZ 1024
/*определяем существование файла*/ bool EXISTF( const char name_f[] ) { return( access( name_f, 0 )!=-1 ) ? true : false; }
//стуктура является массивом и содержит разделители, идентификаторы и прочую дребедень(нужную) struct id { char *ident[ 10 ]; //идентификаторы int number; //количество char value[ 50 ]; //Название } ident_acess[]={ // можно добавит еще операторорв равнозначных begin record (до 10 шт)но end всегда первый элемент { {"end", "begin", "record", "class", "case"}, {5}, {"BLOCK"} }, { {"//"}, {1}, {"COMMENT1"} }, { {"{", "}"}, {2}, {"COMMENT2"} }, { {"(**)"}, {1}, {"COMMENT3"} }, { {"'"}, {1}, {"TEXT"} }, { {";:,./*^#=-+'[]{}<>()"}, {1}, {"DELIMITERS"} } };
//Функцию использует препроцессор int FNDelm( const char *elm_name ) { int i, c=NON; for( i=0; i<N; i++ ) if( stricmp(ident_acess[ i ].value, elm_name)==0 ) { ++c; break; } return( c>NON ) ? i : c; }
//Класс содержит функцию TMPread() //и это вся с него польза (в данном случае) class analys {
public: analys( char *srcf="main.pas" ); void TMPread(); ~analys(); protected: FILE *code_file; id *ids;
};
//К о н с т р у к т о р analys::analys( char *srcf ) { int i, j, c;
ids=&ident_acess[ 0 ];
//файл с кодом() if( EXISTF( srcf ) ) { code_file=fopen( srcf, "r" ); if( !code_file ) { perror( "Error: Cant open file" ); exit( 1 ); } } else { printf( "Cant open source file %s", srcf ); exit( 1 ); } } //Д е с т р к т о р analys::~analys() { fcloseall(); }
//О б р а б о т к а void analys::TMPread() { int i, j, c, FLAG, small_flag, ch, a_count; long curpos; char temp[ MAXSZ ], buf[ MAXSZ ], *tmp;
fseek( code_file, 0L, SEEK_SET ); for( i=0, a_count=0; (ch=(fgetc(code_file)))!=EOF; ) {
//читаем слово FLAG=0; for( j=0; j<strlen(ids[ DELIMITERS ].ident[ 0 ]); j++ ) { if( ch==ids[ DELIMITERS ].ident[ 0 ][ j ] || ch=='\n' || ch=='\t' || ch==' ' ) { FLAG=1; break; } }
if( FLAG==0 ) { buf[ i ]=ch; ++i; } //Указатель находится на символе разделителе //переменная buf содержит все что до него //переменная ch содержит сам символ разделитель DELIMITERS else if( FLAG==1 ) { small_flag=0; buf[ i ]='\0';
curpos=ftell( code_file );
//text if( small_flag==0 ) { if( ch==ids[ TEXT ].ident[ 0 ][ 0 ] ) { for( j=i; buf[ j ]!=EOF; j++ ) { if( (buf[ j ]=(fgetc(code_file)))=='\n' && buf[ j-1 ]!='\\' ) break;
else if( buf[ j ]==ids[ TEXT ].ident[ 0 ][ 0 ] ) { small_flag=2; break; } } if( small_flag>0 ) { if( buf[ j ]!=EOF ) ch=buf[ j ]; else ch='\0'; buf[ j ]='\0'; } else { fseek( code_file, curpos, SEEK_SET ); buf[ i ]='\0'; } } }
//Комментарий 1 if( small_flag==0 ) { temp[ 0 ]=ch; temp[ 1 ]=fgetc( code_file ); //считать следующий символ temp[ 2 ]='\0';
for( j=0; j<ids[ COMMENT1 ].number; j++ ) { if( strcmp( temp, ids[ COMMENT1 ].ident[ j ])==0 ) { for( ; (buf[ i ]=(fgetc(code_file)))!='\n' && buf[ i ]!=EOF; i++ ) ; if( buf[ i ]!=EOF ) ch=buf[ i ]; else ch='\0'; buf[ i ]='\0'; small_flag=1; break; } } if( small_flag==0 ) fseek( code_file, curpos, SEEK_SET ); }
//Комментарий 2 if( small_flag==0 ) { temp[ 0 ]=ch; temp[ 1 ]='\0';
if( strncmp(temp, ids[ COMMENT2 ].ident[ 0 ], 1)==0 ) { for( j=i; (buf[ j ]=(fgetc(code_file)))!=EOF; ) { if( buf[ j ]==ids[ COMMENT2 ].ident[ 1 ][ 0 ] ) { small_flag=2; break; } else j++; } if( small_flag>0 ) { if( buf[ j ]!=EOF ) ch=buf[ j ]; else ch='\0'; buf[ j ]='\0'; } else { ch='\0'; buf[ i ]='\0'; } } }
//Комментарий 3 if( small_flag==0 ) { temp[ 0 ]=ch; temp[ 1 ]=fgetc( code_file ); //считать следующий символ temp[ 2 ]='\0';
if( strncmp(temp, ids[ COMMENT3 ].ident[ 0 ], 2)==0 ) { for( j=i; (buf[ j ]=(fgetc(code_file)))!=EOF; ) { if( buf[ j ]==ids[ COMMENT3 ].ident[ 0 ][ 3 ] && buf[ j-1 ]==ids[ COMMENT3 ].ident[ 0 ][ 2 ] ) { small_flag=1; break; } else j++;
} if( small_flag>0 ) { if( buf[ j ]!=EOF ) ch=buf[ j ]; else ch='\0'; buf[ j-1 ]='\0'; } else { ch='\0'; buf[ i-1 ]='\0'; }
} if( small_flag==0 ) fseek( code_file, curpos, SEEK_SET ); }
//ПРоверка на баланс if( small_flag==0 ) {
for( j=1; j<ids[ BLOCK ].number; j++ ) { if( strncmpi( buf, ids[ BLOCK ].ident[ j ], strlen(ids[ BLOCK ].ident[ j ]))==0 ) { printf( " [%s-+->", ids[ BLOCK ].ident[ j ] ); ++a_count; } } if( strncmpi(ids[BLOCK].ident[ 0 ], buf, 3)==0) { printf( "<--%s] ", ids[BLOCK].ident[ 0 ] ); --a_count; } } i=0; } }
if( a_count==0 ) printf( "\n\nGOOD!!!" ); else printf( "\n\nBAD !!!" ); return; }
void main( int argc, char *argv[] ) { analys CODEFILE( "main.pas" );
CODEFILE.TMPread(); getch();
return; }
|
|