/*词法分析源代码 2020.3.18*/
/*编译样例
function
x= 9;
if x>0 then
x= 2*x+1/3;
end-func
#
*/
//function x= 9;if x>0 then x= 2*x+1/3;end-func#
#include<stdio.h>
#include<string.h>
char prog[80],token[8];
char ch;
int syn,p,m,n,sum;
char * rwtab[6]={"function","if","then","while","do","end-func"};
void scaner();
void scaner()//扫描函数
{
switch(ch){
default:
if((ch >= 'a' && ch <= 'z')||(ch >= 'A' && ch <= 'Z'))
{//判断字符
m=0;
while((ch >= 'a' && ch <= 'z')||(ch >= '0' && ch <='9')||(ch >= 'A' && ch <= 'Z'))
{
token[m++]=ch;//放进token里面
ch=prog[p++];//把下一个字符赋给ch
}
token[m++]='\0';
//ch = prog[--p];
p--;
syn = 10;
for(n = 0;n<6;n++){
if(strcmp(rwtab[n],token)==0)
{
syn=n+1;
break;
}
}
}
else if(ch>='0'&&ch<='9')
{
sum = 0;
while(ch>='0' && ch<='9')
{
sum = sum * 10 + (ch-'0');
ch=prog[p++];//
}
//ch=prog[--p];
p--;
syn=11;
}
else if(ch==' '){
ch=prog[p];
syn=100;
}
else{
int n=p-1;
syn=-1;
break;
case '#':
for(int i=0;i<8;i++)
token[i]=NULL;
syn=0;
token[0]=ch;
break;
case '<':
m = 0;
token[m++]=ch;
ch=prog[p++];
if(ch=='>'){
syn=21;
token[m++]=ch;
}
else
if(ch == '=')
{
syn = 22;
token[m++]=ch;
}
else
{
syn = 20;
ch =prog[--p];
}
break;
case '>':
m = 0;
token[m++]=ch;
ch=prog[p++];
if(ch=='='){
syn=24;
token[m++]=ch;
}
else{
syn=23;
ch=prog[--p];
}
break;
case '=':
m=0;
token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=25;
token[m++]=ch;
}
else{
syn=18;
ch=prog[--p];
}
break;
case '+': syn = 13;token[0]=ch;break;
case '-': syn = 14;token[0]=ch;break;
case '*': syn = 15;token[0]=ch;break;
case '/': syn = 16;token[0]=ch;break;
case ':=':syn=18;token[0]=ch;break;
case '<>':syn=21;token[0]=ch;break;
case '<=':syn=22;token[0]=ch;break;
case '>=':syn=24;token[0]=ch;break;
//case '=':syn=25;token[0]=ch;break;
case ';':syn=26;token[0]=ch;break;
case '(':syn=27;token[0]=ch;break;
case ')':syn=28;token[0]=ch;break;
}
}
}
int main(){
p=0;
printf("\nplease input string:\n");//输入要分析的字符串
do
{
scanf("%c",&ch);
prog[++p]=ch;//放入一个叫prog的数组里面
}while(ch!='#');//输入直到出现#为止
p=0;
do{
ch=prog[p++];
scaner();
switch(syn){//syn控制不同的case,syn是单词类型
case 100:break;
case 11:printf("\n(%d,%d)",syn,sum);break;
case -1:printf("input error\n");break;
default:printf("\n(%d,%s)",syn,token);break;
}
}while(syn!=0);
}
跑出的结果,和课本给出的例子一致
这学期编译原理的课程第一个实验就拖了4周,不愧是我
sublime和终端一起用还是挺不错的
这次就用到了比较简单的unix编译和运行指令
文件所在目录输入gcc -o xxx xx.c和./xxx