2007년 04월 11일
유한 오토마타 스트링 인식기 파일입출력
///////////// All edited By Muzie. ver 0.001 ////////////////
///////////// 최종수정 2007.04.10 /////////////////
////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
struct { // 배열의 인덱스로 쓰기 위한 구조체 정의.상태전이함수가 저장될 구조체.
int current_state;
int input_symbol;
int next_state;
}state[MAX];
char first_state[80]; // 처음상태.
char *all_state[MAX]; // 상태는 2글자 이상이 될수 있으s니 포인터형 배열로. 상태들의 집합.
char symbol[MAX-50]; // 입력심볼은 약간 적게.
char *end_state[MAX]; // 종료상태도 포인터형 배열로.
static int id4=0; // 상태전이함수 개수. 초기값 0
static int id3=0; // 종료상태 개수. 초기값 0
int is_what_cstate(char *cs,int id2){ // 배열의 인덱스로 쓰기 위해 입력된 상태전이함수를 상수화 시킴.
int cnt;
for(cnt=0;cnt<id2;cnt++) // 모든 상태의 집합을 탐색한다.
{
if(strncmp(cs,all_state[cnt],strlen(cs))==0) return cnt;
}
return -1;
}
int is_what_symbol(char is,int id1){ // 입력받은상태전이함수 심볼값.
int cnt;
for(cnt=0;cnt<id1;cnt++){
if(symbol[cnt] == is) return cnt; // 입력받은 심볼값과 같은 값이 심볼배열에 정의되어있으면 그 인덱스값을 반환.
}
return -1;
}
int is_what_nstate(char *ns,int id2){ // 입력받은 상태전이함수 전이된 상태값.
int cnt;
for(cnt=0;cnt<id2;cnt++){
if(strncmp(all_state[cnt],ns,strlen(ns))==0) return cnt; // 입력되어있는 상태값과 같은 값이 있으면 그 인덱스를 반환.
}
return -1;
}
int is_end_mission(int idx){ // 종료조건인지 검사.
int cnt;
for(cnt=0;cnt<id3;cnt++)
{
if(strncmp(end_state[cnt],all_state[state[idx].next_state],strlen(end_state[cnt]))==0) return 1;
else return 0;
}
return -1;
}
int is_delta(char *first_state, char *input_temp,int input_stlen){
int cnt;
int cnt2;
int tem;
int t=0;
for(cnt2=0;cnt2<id4;cnt2++)
{
if(strncmp(first_state,all_state[state[cnt2].current_state],strlen(first_state)) == 0 && input_temp[t] == symbol[state[cnt2].input_symbol])
tem= cnt2; // 처음상태에서 입력심볼을 받아 전이된 상태의 인덱스를 잠깐 저장.
}
t++;
for(cnt=0;cnt<id4;cnt++) // 위에서 결정된 다음상태를 처음상태로 입력받아서
for(cnt2=0;cnt2<id4;cnt2++){
if(strncmp(all_state[state[tem].next_state],all_state[state[cnt2].current_state],strlen(all_state[state[tem].next_state]))==0 && input_temp[t] == symbol[state[cnt2].input_symbol])
{ //printf("next->%s\n",all_state[state[tem].next_state]);
tem=cnt2;
t++;
}
}
return tem; // 최종인덱스값을 반환.
}
int _set_DFA(char *filename){ // DFA를 정의하는 함수.
FILE *fp=fopen(filename,"r"); // 읽을 파일을 불러온다.
char buf[80],cs[15],ns[15],is;
int id1=0,id2=0; // 카운트에 쓰일 변수 선언.
while(!feof(fp))// 시작조건을 셋할 부분. 끝이 아닌동안 읽어라.
{
fgets(buf,80,fp); // 한줄을 읽어와 first_state에 저장.
strcpy(first_state,buf);
if(strcmp(";",buf)) break; // 만약 ; 가 발견되면 루프를 빠져나가라.
} // first_state에는 처음상태 q0 or q1....이 입력되어있다.
fgets(buf,80,fp);
while(!feof(fp)) // 입력심볼들의 집합을 입력할 부분. ; 아닌동안.
{
fgets(buf,80,fp);
if(buf[0]==';') break; // 한칸 엔터면 그냥 넘기고
symbol[id1]=buf[0]; // symbol 들에 저장해라.
id1++; // 입력심볼들의 개수파악을 위한 변수.
}
while(!feof(fp)){ // 상태들의 집합을 입력할 부분.
fgets(buf,80,fp); // 한줄 읽어서 버퍼에 잠깐 넣어둔다.
if(buf[0]==';') break; // ;면 루프이탈.
all_state[id2] = (char*) malloc(strlen(buf)*sizeof(char)); // 동적메모리할당. 올스테이트 변수에 동적할당된 2차원배열.
strcpy(all_state[id2], buf); // 버퍼에 넣어뒀던것을 저장.
id2++; // 모든상태의 개수파악을 위한 변수.
}
while(!feof(fp)){ // 종료상태들을 입력할부분.
fgets(buf,80,fp); // 한줄 읽는다.
if(buf[0]==';') break; // ;면 루프이탈.
end_state[id3] = (char*)malloc(strlen(buf)*sizeof(char)); // 동적 메모리 할당. 엔드스테이트 변수에 동적할당된 2차원배열.
strcpy(end_state[id3],buf); // 버퍼에 있는것 카피.
id3++;
}
while(!feof(fp)) // 상태전이함수를 입력할 부분.
{
fscanf(fp, "%s\t%c\t%s", cs, &is, ns); // 처음상태 스트링 /탭/ 입력심벌 /탭/ 전이된 상태 스트링.
state[id4].current_state=is_what_cstate(cs,id2);// 구조체에 현재상태값 저장.
state[id4].input_symbol=is_what_symbol(is,id1);// 구조체에 입력심볼값 저장.
state[id4].next_state=is_what_nstate(ns,id2); // 구조체에 다음상태값 저장.
id4++; // 인덱스 증가. 상태전이함수 개수.
}
return 0;
}
void main(int argc,char *argv[])
{
char input_temp[100];
int input_stlen,end,idx;
_set_DFA("data.txt"); // 셋DFA함수에 파일명 넘겨줌. 모든 DFA의 조건들을 불러온다.
strcpy(input_temp,*(argv+1)); // 카피.
input_stlen=strlen(input_temp); // 입력받은 문자열의 길이.
idx=is_delta(first_state,input_temp,input_stlen);
end=is_end_mission(idx);
printf("스트링은 ");
if(end==0) printf("인식되지 않습니다.");
else printf("인식됩니다. 축하합니다 ~ 짝짝짝~");
printf("\nThis Program is Implemented by FEEL\n");
}
/////////////////////////////////////////////////////////////////////
성훈이형이 만들어준 소스로 어떻게 해보려고 하다가 결국엔
전부 다시 다 짜버리는 불상사가 일어났다. 덕분에 이틀을 밤새서
지금은 제정신이 아닌상태 -_-
교수님이 내주신 모든 일련의 프로그래밍 숙제들은 결과적으로
Lexical Analizer를 생성하기 위한 작업이다. 교수님께서는 지금까지
한 모든것을 소화한다면 Lexical A같은 건 배운것을 Mix해서 그냥
해버릴 수 있다고..하신다 -_-;
음... 어떻게;;?
역시 세상은 참 신기하다. 머털도사가 머리카락을 세우고 나니
온갖것으로 변신을 하는것과 같은 원리려나 ; 내가 코드를 다 짜긴
했어도 대체 뭘 할 수 있단건지 모르겠다고 정말 ㅠ_ㅠ
# by | 2007/04/11 18:24 | STUDY | 트랙백 | 덧글(0)




☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]