C语言--简易词法分析器
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int p,m,syn,n,sum; //p和m,作用相当于指针,用来指向下一个字符或回退一个字符,syn用于判别字符种类。
//n为循环控制变量,sum用来判别整型数是否溢出。
char token[10],prog[80]; //全局变量,一个数组用来接收键盘输入,另一个用于词法分析。
char ch; //从键盘输入的字符数组里一个个取出,做判别。
char *keywords[7]={"begin","else","if","while","do","end","then"}; //关键字字符数组。用来和键盘输入的字符串作比较
#include <stdlib.h>
#include <string.h>
int p,m,syn,n,sum; //p和m,作用相当于指针,用来指向下一个字符或回退一个字符,syn用于判别字符种类。
//n为循环控制变量,sum用来判别整型数是否溢出。
char token[10],prog[80]; //全局变量,一个数组用来接收键盘输入,另一个用于词法分析。
char ch; //从键盘输入的字符数组里一个个取出,做判别。
char *keywords[7]={"begin","else","if","while","do","end","then"}; //关键字字符数组。用来和键盘输入的字符串作比较
void Scaner() //词法分析器
{ p=0;
n=0;
ch = prog[p++]; //从键盘输入的字符数组,读取一个字符,用于做判别。p指向下一个字符。
for(n=0;n<10;n++) //初始化用于存储判别过后字符的字符数组
token[n] = ' ';
while(ch==' ') //当读取字符不为空时,开始判别
{
ch = prog[p++]; //为空,p一直往下走。
p++;
}
if((ch>='a'&&ch<='z')||(ch<='Z'&&ch>='A')) //若为字母。
{
m=0;
while((ch>='a'&&ch<='z')||(ch<='Z'&&ch>='A')) //循环,读取下一个为字母的字符。
{
token[m++]= ch; //存进判别过的字符数组
ch = prog[p++];
}
token[m++]='\0';//字符数组后一位设为空。
p--; //p回退一位,因为此时不满足if条件。
syn = 10; //字母的种别码,为10.
for(n=0;n<7;n++)
if(strcmp(token,keywords[n])==0) //读进的字符数组与关键词字符串数组作比较
{
syn=n+1; //若相同,则返回1-6的关键字种别码
break;
}
}
else if(ch>='0'&&ch<='9') //若读进的字符为数字。
{
sum = 0;
while(ch<='9'&&ch>='0') //累加。
{
sum=sum*10+ch-'0'; //由于是字符,所以要手动进位。sum乘10,
ch=prog[p++];
}
p--;
syn = 11;
if(sum>32767) //判断是否溢出。int类型(C语言里)最大为32767,最小为-32766
syn = -1; //种别码为-1,说明溢出。
}
else switch(ch) //若为运算符
{
case '<':
m=0;
token[m++] = ch;
ch = prog[p++];
if(ch=='>') //形成尖括号<>
{
token[m++]=ch;
syn=21; //尖括号的种别码
}
else if(ch=='=') //形成<=
{
token[m++] = ch;
syn = 22;
}
else
{
syn = 20;
p--;
}
break;
case '>': //与<同理
m=0;
token[m++]=ch;
ch=prog[p++];
if(ch=='<')
{
token[m++]=ch;
syn = 21;
}
else if(ch=='=')
{
token[m++]=ch;
syn=24;
}
else
{
syn = 25;
p--;
}
break;
case '(': //与尖括号同理
m=0;
token[m++]=ch;
ch=prog[p++];
if(ch==')')
{
token[m++]=ch;
syn = 26;
}
else
{
syn = 27;
p--;
}
break;
case ')':
m=0;
token[m++]=ch;
ch=prog[p++];
if(ch=='(')
{
token[m++]=ch;
syn=26;
}
else
{
syn=27;
p--;
}
break;
case '+':token[0]=ch;syn = 12;break; //其他的一些运算符处理
case '-':token[0]=ch;syn = 13;break;
case '*':token[0]=ch;syn = 14;break;
case '/':token[0]=ch;syn = 15;break;
case '!':token[0]=ch;syn = 16;break;
case ':':token[0]=ch;syn = 17;break;
case ';':token[0]=ch;syn = 18;break;
case '#':token[0]=ch;syn = 0;break;
default:syn =-1;break;
}
}
{ p=0;
n=0;
ch = prog[p++]; //从键盘输入的字符数组,读取一个字符,用于做判别。p指向下一个字符。
for(n=0;n<10;n++) //初始化用于存储判别过后字符的字符数组
token[n] = ' ';
while(ch==' ') //当读取字符不为空时,开始判别
{
ch = prog[p++]; //为空,p一直往下走。
p++;
}
if((ch>='a'&&ch<='z')||(ch<='Z'&&ch>='A')) //若为字母。
{
m=0;
while((ch>='a'&&ch<='z')||(ch<='Z'&&ch>='A')) //循环,读取下一个为字母的字符。
{
token[m++]= ch; //存进判别过的字符数组
ch = prog[p++];
}
token[m++]='\0';//字符数组后一位设为空。
p--; //p回退一位,因为此时不满足if条件。
syn = 10; //字母的种别码,为10.
for(n=0;n<7;n++)
if(strcmp(token,keywords[n])==0) //读进的字符数组与关键词字符串数组作比较
{
syn=n+1; //若相同,则返回1-6的关键字种别码
break;
}
}
else if(ch>='0'&&ch<='9') //若读进的字符为数字。
{
sum = 0;
while(ch<='9'&&ch>='0') //累加。
{
sum=sum*10+ch-'0'; //由于是字符,所以要手动进位。sum乘10,
ch=prog[p++];
}
p--;
syn = 11;
if(sum>32767) //判断是否溢出。int类型(C语言里)最大为32767,最小为-32766
syn = -1; //种别码为-1,说明溢出。
}
else switch(ch) //若为运算符
{
case '<':
m=0;
token[m++] = ch;
ch = prog[p++];
if(ch=='>') //形成尖括号<>
{
token[m++]=ch;
syn=21; //尖括号的种别码
}
else if(ch=='=') //形成<=
{
token[m++] = ch;
syn = 22;
}
else
{
syn = 20;
p--;
}
break;
case '>': //与<同理
m=0;
token[m++]=ch;
ch=prog[p++];
if(ch=='<')
{
token[m++]=ch;
syn = 21;
}
else if(ch=='=')
{
token[m++]=ch;
syn=24;
}
else
{
syn = 25;
p--;
}
break;
case '(': //与尖括号同理
m=0;
token[m++]=ch;
ch=prog[p++];
if(ch==')')
{
token[m++]=ch;
syn = 26;
}
else
{
syn = 27;
p--;
}
break;
case ')':
m=0;
token[m++]=ch;
ch=prog[p++];
if(ch=='(')
{
token[m++]=ch;
syn=26;
}
else
{
syn=27;
p--;
}
break;
case '+':token[0]=ch;syn = 12;break; //其他的一些运算符处理
case '-':token[0]=ch;syn = 13;break;
case '*':token[0]=ch;syn = 14;break;
case '/':token[0]=ch;syn = 15;break;
case '!':token[0]=ch;syn = 16;break;
case ':':token[0]=ch;syn = 17;break;
case ';':token[0]=ch;syn = 18;break;
case '#':token[0]=ch;syn = 0;break;
default:syn =-1;break;
}
}
int main()
{ p=0;
printf("Please enter a string:\n");
gets(prog); //键盘输入一组字符。
do
{
Scaner();//做词法分析
if(syn<10&&syn>0)
{printf("This is keywords!\n");break;} //关键字
else if(syn==10)
{printf("This is a words!\n");break;} //标识符
else if(syn==11)
{printf("This is a number!\n");break;} //数字
else
{printf("Other words!\n");break;} //运算符或者结束符#
}
while(syn!=0);
return 0;
}
{ p=0;
printf("Please enter a string:\n");
gets(prog); //键盘输入一组字符。
do
{
Scaner();//做词法分析
if(syn<10&&syn>0)
{printf("This is keywords!\n");break;} //关键字
else if(syn==10)
{printf("This is a words!\n");break;} //标识符
else if(syn==11)
{printf("This is a number!\n");break;} //数字
else
{printf("Other words!\n");break;} //运算符或者结束符#
}
while(syn!=0);
return 0;
}