매크로 프로세서 작성중 오류..(도저히 못 찾겠네요...)
글쓴이: San / 작성시간: 일, 2004/11/28 - 1:11오전
#include <stdio.h> #include <string.h> #include <fcntl.h> #define TT void GoPass1(char buf[40]); void GoPass2(char buf[40]); int main(int argc, char *argv[]) { FILE *infp, *outfp; char buf[40]; infp = fopen(argv[1], "r"); outfp = fopen(argv[2], "w"); if(argc < 3) { printf("파일명 원본파일명 목적파일명\n"); printf("위의 형식을 따라 주세요\n"); exit(1); } while(fgets(buf, 40, infp) != NULL) { GoPass1(buf); } /* while(fgets(buf, 40, outfp) != NULL) { GoPass2(); }*/ fclose(infp); fclose(outfp); } void GoPass1(char buf[40]) { FILE *tmpfp, *insoo1fp, *define; // 패스1과 2사이의 임시파일, 형식인수테이블파일, 매크로정의 테이블파일 char *word[5]; // 인덱스 테이블생성시 사용. char cmpbufword[10],*cmpindexword,indexbuf[40]; // 형식인수테이블과 원본테이블에서 읽은 문자비교시. // 버퍼에서 읽은 토큰, 형식인수테이블에서 읽은 토큰, 인덱스테이블에서 읽은 한 라인. // 원본파일에서 읽은 한 라인은 함수에 buf인수로 넘어온다. char tmpbuf[10], *cmpindex; // 형식인수 인덱스로 치환하기 위해 그 뒤의 라인을 임시로 저장. 인수명을 인덱스로 치환하기 위한 인덱스 저장. int i = 0,j; // 각 기능에서 임시로 사용하는 카운터변수 int index = 0; static int isMacroBody = 0; // 매크로 정의 본체를 읽는 중인지 아닌지 체크.1혹은 0. int chP = 0; int p = 0; if(strstr(buf, "MACRO")!=NULL) { // 읽은 라인에 MACRO 라는 단어가 있으면 인수표 생성시작. insoo1fp = fopen("insoo","a"); define = fopen("define","a"); fprintf(define,"%s\n",buf); isMacroBody = 1; while((word[i] = strtok(buf,",\t \n"))!=NULL) { i++; buf = (char *)0; } for(j = 2; j < i; j++) { fprintf(insoo1fp,"#%d %s\n", index =(j-1), word[j]); } fclose(insoo1fp); fclose(define); return; }//여기까지가 매크로 제목줄의 인수로 인수표를 생성하는 부분.메인으로 복귀. if(isMacroBody == 0) { // 매크로와 관계 없는 부분은 그냥 tmp에 복사한다. tmpfp = fopen("tmp","a"); fputs(buf, tmpfp); fclose(tmpfp); return; }// 비 매크로 부분 복사후 메인으로 복귀 else if(isMacroBody == 1) { // 매크로 바디부분처리 insoo1fp = fopen("insoo","r"); define = fopen("define","a"); if(strstr(buf,"ENDM")!=NULL) { isMacroBody = 0; fputs(&buf[0],define); return; // GoPass1 함수를 빠져나가 main으로. } while(buf[chP]!='\n') { printf("1111111111\n");fflush(stdout); while(buf[chP]==' '||buf[chP]=='\t'||buf[chP]==',') chP++; // 공백을 뛰어넘고 (공백부분일때의 chP의 증가) while(buf[chP]!=' '&&buf[chP]!='\t'&&buf[chP]!=','&&buf[chP]!='\n') { // 문자부분은 한문자씩 공백이 아닌지 비교해가면서 공백이면 루프빠져나감. cmpbufword[p]=buf[chP]; // 배열의 현재 행에 복사 p++; // 단어가 읽히기 시작한 순간부터 p값 증가. chP++; // 해당 버퍼 전체에 대한 포인터 (chP값의 문자부분을 읽을때의 증가부분.) } // 하나의 단어를 다 저장하면 빠져나간다. cmpbufword[p] = '\0'; // 문자열 맨 끝에 NULL추가. while(fgets(indexbuf,40,insoo1fp)!=NULL) { cmpindex = strtok(indexbuf," ,\t\n"); // 첫번째 토큰은 치환할 경우를 대비하여 변수에 저장해둠. cmpindexword = strtok(NULL," ,\t\n"); // 두번째 토큰(아규먼트이름)의 주소를 변수에 저장. if(!strcmp(cmpindexword,cmpbufword)) { printf("ok\n");//원본파일에서 잘라낸 토큰과 인덱스테이블에서 읽은 토큰이 같으면 화면에 ok출력및 if문 진입. strcpy(tmpbuf,&buf[chP]); // 치환의 바로 뒷부분을 치환후 붙이기 위해 저장. strcpy(&buf[chP-p],cmpindex); // 치환할 부분의 시작주소에 인덱스를 치환해 넣는다. chP = chP-p+strlen(cmpindex); // 치환한 바로 뒷 부분을 chP가 가리키게 한다. strcpy(&buf[chP], tmpbuf); // chP가 가리키는 부분에 저장해 두었던 치환한 바로 뒷부분에 이어지는 문자열을 복사해 넣는다. fputs(&buf[0], define); break; } // if(!strmcp) - END p = 0; }//while(fgets(indexbuf,~~~~) { ) - END p = 0; rewind(insoo1fp); }//while(buf[chP-1]!='\0') - END fclose(define); fclose(insoo1fp); }// else if(isMacroBody == 1) { - END }// GoPass1(car buf[40]) { - END
코드는 상기와 같습니다...
증상이 하도 이상하여 원인을 알 수가 없네요...
인덱스 테이블과 정의 테이블을 모두 화일로 구현하였는데요
아규먼트가 꼭 'X' 혹은 'XXX'처럼 X
자가 들어가는 것만 제대로 치환이 되고,
나머지는 원래 문자 뒤에 치환이 되어 정의 테이블로 들어가는군요.
예를 들면
MOVES MACRO X, Y, Z MOV AX, X MOV BX, Y MOV CX, Z ENDM MAIN SEGMENT MOVES 1,2,3 MOV AH, 4CH INT 21H MAIN ENDS END
가 원본일 경우 정의 테이블에는
OVES MACRO X, Y, Z MOV AX, #1 MOV BX, Y#2 MOV CX, Z#3 ENDM
로 들어가고 있습니다.
인수표를 만드는 순서도 바꾸어보고 , 밑의 명령어순서도 바꾸어 보았는데
꼭 X자가 들어간 것만 골라서 (순서에 상관없이) 제대로 치환되고
나머지는 글자수에 상관없이 원래 이름바로뒤에 '#숫자' 가오니..
한번 X자 를 아규먼트 에서 아예 제외하고 실행하였더니 모든
아규먼트가 하나씩 밀려 나오고 제대로 된 것이 없었습니다.
이런 경우는 무엇이 문제인지..
제가 무엇을 놓치고 있는지 모르겠네요...
시간이 없어 속이 타는 상황이고
가능한한 내일 새벽까지도 깨어 있을 작정이니
보시고 꼭좀 도와주시면 감사하겠습니다.
물론 제가 버그를 발견 하였을 시는 발견 즉시 여기로 와 답글을
달도록 하지요.
Forums:
오류를 찾았습니다.
무심코 넣은 p = 0; 하나.(위의 것)
이 문제였군요.
깊이 생각하지 않고 '여기도 들어 가겠지' 식으로 넣어놓고 잊어버렸
었습니다. 인덱스갯수만큼 비교하기 전에 p를 초기화 시켜 버리면
앞에 바꾼 글자수를 기억못하는 것은 당연하겠지요.
아마도 X만 괜찮았던 것은 X가 첫번째 인덱스여서 루핑으로 다시
돌아가지 않아서일텐데, 제가먼저 테스트 해 본 인덱스 순서 바꾸기도
무슨 정신에선지 잘못 한 듯 합니다.
라면하나 먹고 다시 와서 붙잡으니 힘이 나네요 ^^
gdb print로 해당 구역 내 모든 버퍼를 다
트레이스 해서 찾았습니다 ^^
그럼 이만~
댓글 달기