#include #include #include #define STR_MAX 256 /* 1行の最大長 */ /* グローバル変数 */ char gt_line[STR_MAX]; /* 1行データバッファ */ char token[STR_MAX]; /* 取得トークン*/ /* プロトタイプ宣言 */ char *get_token(void); /* トークン分割関数 */ char *analyze_token(void); char *get_token(void) { char *r, *rtk, ch ;/*rは配列gt_lineを、rtkは配列tokenを操作するポインタ変数である*/ r = gt_line; /* ポインタの初期化*/ rtk = token; /* ポインタの初期化*/ while(*r == ' ' || *r == '¥t' || *r == '¥n') /* 空白を読み飛ばす */ ++r; if(*r == '¥0'){ /* バッファ空*/ token[0] = '¥0'; return(token); } /* 識別子((英字)(英字|数字))*/ if(isalpha(*r)){/*一文字目は英字*/ do{ *rtk++ = *r++; }while(isalnum(*r) && *r !='¥0'); /* 2文字目以降は英数字 */ /* 数字 */ }else if(isdigit(*r)){ do{ *rtk++ = *r++; }while((isalnum(*r) || *r == '.' || toupper(*r) == 'E') && *r !='¥0');/*小数点付きの数字やe*/ /* 二文字からなる記号や演算子(<= , >= , != , :=) */ }else if(*r == '<' || *r == '>' || *r == '!' || *r == ':'){ do{ *rtk++ = *r++; }while(*r == '=' && *r !='¥0'); /* その他の文字(一文字からなる記号や演算子など) */ }else *rtk++ = *r++; *rtk = '¥0'; /* 文字列終端 */ strcpy(gt_line, r); /* 残りの文字列をコピー */ return(token); } /*字句解析関数*/ char *analyze_token(void){ char *q ,ch2;/*識別子、数字のためのポインタ*/ q=token; /*予約語*/ if(strcmp(token, "begin")==0 ) printf("%s ",token); else if(strcmp(token, "call")==0 ) printf("%s ",token); else if(strcmp(token, "const")==0 ) printf("%s ",token); else if(strcmp(token, "do")==0 ) printf("%s ",token); else if(strcmp(token, "else")==0 ) printf("%s ",token); else if(strcmp(token, "end")==0 ) printf("%s ",token); else if(strcmp(token, "if")==0 ) printf("%s ",token); else if(strcmp(token, "odd")==0 ) printf("%s ",token); else if(strcmp(token, "procedure")==0 ) printf("%s ",token); else if(strcmp(token, "then")==0 ) printf("%s ",token); else if(strcmp(token, "var")==0 ) printf("%s ",token); else if(strcmp(token, "while")==0 ) printf("%s ",token); /*算術演算子*/ else if(strcmp(token, "+")==0 ) printf("%s ",token); else if(strcmp(token, "-")==0 ) printf("%s ",token); else if(strcmp(token, "*")==0 ) printf("%s ",token); else if(strcmp(token, "/")==0 ) printf("%s ",token); /*記号*/ else if(strcmp(token, ".")==0 ) printf("%s ",token); else if(strcmp(token, ",")==0 ) printf("%s ",token); else if(strcmp(token, ";")==0 ) printf("%s ",token); else if(strcmp(token, "(")==0 ) printf("%s ",token); else if(strcmp(token, ")")==0 ) printf("%s ",token); /*関係演算子*/ else if(strcmp(token, ">")==0 )printf("gt "); else if(strcmp(token, "<")==0 ) printf("lt "); else if(strcmp(token, ">=")==0 ) printf("geq "); else if(strcmp(token, "<=")==0 ) printf("leq "); else if(strcmp(token, "=")==0 ) printf("eq "); else if(strcmp(token, "!=")==0 ) printf("neq "); /*代入記号*/ else if(strcmp(token, ":=")==0 ) printf("become "); /*識別子*/ else if(isalpha(*q)){ do{ q++; }while(isalnum(*q) && *q !='¥0'); printf("ident(%s) ",token); } /*数字*/ else if(isdigit(*q)){ do{ q++; }while(isalnum(*q) && *q !='¥0'); printf("number(%s) ",token); } /*その他はnull出力*/ else printf("null "); } /*関数get_tokenをテストするためのメインプログラム*/ int main(int argc,char *argv[]){ /*ファイル入力*/ if(argc==2){ /*ファイル変数宣言*/ FILE *in_file; /*ファイルのオープンチェック*/ in_file=fopen(argv[1],"r"); if(in_file==NULL){ printf("Cannot open %s¥n",in_file); exit(-1); } /* ファイルから1行読み込み */ while(fgets(gt_line, STR_MAX, in_file) != NULL){ while(1){ get_token(); if(*token == '¥0') /* 1行分終了 */ break; else analyze_token(); } printf("¥n");/*改行処理を行う*/ } fclose(in_file); /* ファイルを閉じる*/ } }