📄 语法分析程序.c
字号:
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<malloc.h> /* malloc()等 */
#include<limits.h> /* INT_MAX等 */
#include<stdlib.h> /* atoi() */
#include<io.h> /* eof() */
#include<math.h> /* floor(),ceil(),abs() */
#include<process.h> /* exit() */
#include<time.h>
#define MAX 20
int kk=0;
int statement();
int yucu();
int expression();
int term();
int factor();
char ch;
FILE *fp;
typedef struct //二元组
{
int syn; //种别编码
char value[MAX]; //值
}WS;
WS wd;
void getbc() //检查ch是否为空白符,是的话,继续取下一个字符,直到不为空
{
while(ch==' ') ch=fgetc(fp);
}
int letter() //判断ch是否为字母
{
if((ch>='A')&&(ch<='Z')||(ch>='a')&&(ch<='z')) return 1;
else return 0;
}
int digit() //判断ch是否为数字
{
if((ch>='0')&&(ch<='9')) return 1;
else return 0;
}
int reserve(char *token) //查关键字表,判断token中的字符串是否为关键字
{
int key=10,i;
char WORDS_KEY[8][20]={"begin","int","char","if","else","end","while","void"};
for(i=0;i<8;i++)
if(strcmp(token,WORDS_KEY[i])==0) {key=i+1; break;} //与关键字比较
return key;
}
void error() //错误调用函数
{
printf("There has some unlawful words!");
}
int scaner() //扫描函数,主要算法
{
char token[20];
WS wd;
int c;
int i=0;
ch=fgetc(fp);
getbc(fp);
if(letter()) //是否为字母,是的话继续取字符,直到取的词不是字母或数字。调用reserve(char *token)判断是否为关键字。
{
while(letter()||digit())
{
token[i]=ch;
ch=fgetc(fp);
i++;
}
token[i]='\0';
fseek(fp,-1L,1); //退一个字符
c=reserve(&token);
if(c!=10) { wd.syn=c;strcpy(wd.value,token); }
else { wd.syn=10;strcpy(wd.value,token);}
}
else if(digit()) //是否为数字,是的话继续取字符,直到取的词不是数字。
{
while(digit())
{
token[i]=ch;
ch=fgetc(fp);//读下一个字符
i++;
}
fseek(fp,-1L,1);
token[i]='\0';
wd.syn=11;strcpy(wd.value,token);
}
else
{
switch(ch) //判断可识别字符
{
case '+': wd.syn=13; break;
case '-': wd.syn=14; break;
case '*': wd.syn=15; break;
case '/': ch=fgetc(fp);
if(ch=='*')
{
while(1)
{
ch=fgetc(fp);
if(ch=='*')
{
ch=fgetc(fp);
if(ch=='/')
break;
}
}
wd.syn=-1;
break;
}
fseek(fp,-1L,1);wd.syn=16; break;
case '<': wd.value[0]=ch;ch=fgetc(fp);
if(ch=='>'){ wd.syn=27; break;}
if(ch=='='){ wd.syn=26; break;}
fseek(fp,-1L,1);
wd.syn=25; break;
case '>': wd.value[0]=ch;ch=fgetc(fp);
if(ch=='='){ wd.syn=28; break;}
fseek(fp,-1L,1);
wd.syn=29; break;
case ':':wd.value[0]=ch;ch=fgetc(fp);
if(ch=='='){wd.syn=18; break;}
fseek(fp,-1L,1);
wd.syn=19; break;
case ';': wd.syn=24; break;
case '(': wd.syn=20; break;
case ')': wd.syn=21; break;
case '{': wd.syn=22; break;
case '}': wd.syn=23; break;
case '=': wd.syn=17; break;
default : wd.syn=0; break;
}
}
return wd.syn ;
}
int yucu()
{
statement();//调用statement函数
while(wd.syn==24)//判断是否是分号
{
wd.syn=scaner();
statement();//调用statement函数
}
return 0;
}
int statement()
{
if(wd.syn==10)//判断是否是字母
{
wd.syn=scaner();
if(wd.syn==18)//判断是否是:=
{
wd.syn=scaner();
expression();//调用expression函数
}
else {printf("赋值号错误"); kk=1;}
}
else {printf("语句错误"); kk=1;}
return 0;
}
int expression()
{
term();
while(wd.syn==13||wd.syn==14)//判断如果是加或减
{
wd.syn=scaner();
term();//调用term函数
}
return 0;
}
int term()
{
factor();
while(wd.syn==15||wd.syn==16)
{
wd.syn=scaner();
factor();//调用factor函数
}
return 0;
}
int factor()
{
if(wd.syn==10 ||wd.syn==11)//判断如果是字符或数字
wd.syn=scaner();
else if(wd.syn==20)
{
wd.syn=scaner();
expression();//调用expression函数
if(wd.syn==21)
wd.syn=scaner();
else{printf("')'错误"); kk=1;}
}
else {printf("表达式错误"); kk=1;}
return 0;
}
main()
{
if((fp=fopen("file.txt","r+"))==NULL) printf("文件打开失败");
wd.syn=scaner(fp);
if(wd.syn==1)
{
wd.syn=scaner();
yucu();//调用yucu函数
if(wd.syn==6)
{
wd.syn=scaner();
if(wd.syn==0&&(kk==0))
printf("success");
}
else { if(kk!=1) printf("缺少end"); kk=1;}
}
else {printf("begin错误"); kk=1;}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -