#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define _KEY_WORD_END "waiting for your expanding" //定義關鍵字結束标志
typedef struct
{
int typenum;
char * word;
}WORD;
char input[255]; //輸入換緩沖區
char token[255]=""; //單詞緩沖區
int p_input; //輸入換緩沖區指針
int p_token; //單詞緩沖區指針
char ch; //目前所讀的字元
char *rwtab[]={"begin","if","then","while","do","end",_KEY_WORD_END}; //可擴充的關鍵字數組
WORD * scaner(); //詞法掃描函數,獲得關鍵字
main()
int over=1;
WORD *oneword;
oneword=(WORD *)malloc(sizeof(WORD));
printf("請輸入源代碼(以#結束):");
scanf("%[^#]s",input); //讀入源程式字元串到緩沖區,以#結束,允許多行輸入
p_input=0;
printf("你輸入的代碼:%s\n\n",input);
while(over<1000&&over!=-1) //對源程式進行分析,直至結束符#
{
oneword=scaner(); //獲得一個新單詞
printf("單詞符号:%s\t種别碼:%d\n",oneword->word,oneword->typenum); //列印種别碼和單詞自身的值
over=oneword->typenum;
}
}
char m_getch()
{
ch=input[p_input];
p_input=p_input+1;
return (ch);
void getbc()//去掉空白字元
while(ch==' '||ch==10)
{
ch=input[p_input];
p_input=p_input+1;
void concat()//拼接單詞
token[p_token]=ch;
p_token=p_token+1;
token[p_token]='\0';//一個單詞結束
int letter()//判斷是否字母
if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')
return 1;
else
return 0;
int digit()//判斷是否數字
if(ch>='0'&&ch<='9')
else
int reserve()//檢索關鍵字表格
int i=0;
while(strcmp(rwtab[i],_KEY_WORD_END)) //數組中的單詞跟輸入的單詞比較
if(!strcmp(rwtab[i],token))
{
return i+1;
}
i=i+1;
}
return 10;
void retract()//回退一個字元
p_input=p_input-1;
WORD *scaner()//掃描單詞
WORD *myword ;
myword=(WORD *)malloc(sizeof(WORD));
myword->typenum=10;
myword->word="";
p_token=0;
m_getch();
getbc();
if(letter())//字母
{
while(letter()||digit()){
concat();
m_getch();
}
retract();
myword->typenum=reserve();
myword->word=token;
return(myword);
}
else if(digit())//數字
{
while(digit())
{
concat();
m_getch();
}
retract();
myword->typenum=20;
myword->word=token;
return(myword);
}
else //其他
{
switch(ch)
{
case '+':
myword->typenum=13;
myword->word="+";
return(myword);
break;
case '-':
myword->typenum=14;
myword->word="-";
return(myword);
break;
case '*':
myword->typenum=15;
myword->word="*";
return(myword);
break;
case '/':
myword->typenum=16;
myword->word="/";
return(myword);
case ':': m_getch();
if(ch=='='){
myword->typenum=18;
myword->word=">=";
return(myword);
}
retract();
myword->typenum=17;
myword->word=":";
case '<': m_getch();
myword->typenum=21;
myword->word="<=";
else if(ch=='>'){
myword->typenum=22;
myword->word="<>";
retract();
myword->typenum=20;
myword->word="<";
break;
case '>': m_getch();
myword->typenum=24;
retract();
myword->typenum=23;
myword->word=">";
return(myword);
case '=':
myword->typenum=25;
myword->word="=";
case ';':
myword->typenum=26;
myword->word=";";
case '(':
myword->typenum=27;
myword->word="(";
case ')':
myword->typenum=28;
myword->word=")";
case '#':
myword->typenum=0;
myword->word="OVER";
default:
myword->typenum=-1;
myword->word="ERROR";
return(myword);
}
}
