📄 parser.c
字号:
// a.cpp: 主项目文件。
//#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char token[20]; //存放单词符号
char prog[1024]; //存放源程序
char * p; //Prog 指针
char ch; //读取当前字符
int syn,m,n; // syn 特征值
int presyn; //记住前一个特征值,用于判断‘+’,‘-’是否属于后面数值的符号
char * rwtab[9]={"main","int","float","double","char","if","else","do","while"}; //关键字
double sum,decimal,integer;//用于数值单词的分析
int exp,expMark; //指数,指数符号
int flag; //判断正负数
int k;
//词法分析部分
void initialize(); //每次扫描单词之前的一些初始化
void scan(); //扫描,得到单词
void printWord(); //输出单词
//语法分析部分
void expression(); //表达式
void term(); //项
void factor(); //因子
void main(int argc,char * argv[]){
FILE *fp;
if(argc==2)
fp=fopen(argv[1],"r");
else
{
fp=fopen("yjj.txt","r");
if(fp==NULL)
{
printf("\tUsage:%s yjjFileName\n\tThe Default yjjFileName:yjj.txt\n",argv[0]);
getchar();
return;
}
}
if(fp==NULL)
{
printf("File open error:%s\n",argv[1]);
getchar();
return;
}
fread(prog,1024,1,fp);
p=prog-1;
printf("%s\n",prog);
presyn = 0;
k=0;
// do
// {
scan();
printWord();
expression();
if(syn == 1000 && k == 0)
printf("\nSuccess\n");
else
printf("\nError\n");
// }
// while(syn!=-1&&syn!=0&&*(p+1)!='\0');
fclose(fp);
}
//用于单词的输出
void printWord()
{
int i;
switch(syn)
{
case 20 :
for(i = 0; i < exp; i ++)
{
if(expMark == -1)
sum /= 10;
else
sum *= 10;
}
sum = sum * flag;
printf("( 20 , %e )\n",sum);break;
case -1 : printf("ERROR!\n");break;
case 0 : printf("( 0, # )\n");break;
case 1000:break;
default : printf("( %d , %s )\n",syn,token);
}
}
//每次扫描前的一些初始化工作
void initialize()
{
ZeroMemory(token,20); //清空token数组中的内容
p++; //将指针指向下一位要读取的字符
ch=*p; //读取当前字符
m=0; //token的指针
sum=0; //数值初始化为0,包括整数部分interger和小数部分decimal
integer=0;
decimal=0;
exp=0; //exp初始化为0
expMark=0; //指数部分的符号
flag=1; //数值默认为整数
presyn = syn; //记住前一单词的种类
}
//单词扫描
void scan()
{
int i;
initialize();
while(ch==' '||ch=='\t'||ch=='\n')
{
p++;
ch=*p;
}
if(isalpha(ch)) //第一部分:关键字和标识符的识别
{
while(isalnum(ch))
{
token[m++]=ch;
p++;
ch=*p;
}
p--;
token[m]='\0';
for(n=0;n<6;n++) //判断是否为关键字
{
if(strcmp(token,rwtab[n])==0)
{
syn=n+1;
return;
}
}
syn=10; //是标识符
return;
} //第二部分:数值的识别,还要根据presyn进行符号识别
if( isdigit(ch)||ch =='+'||ch =='-' )
{
if(ch=='+')
{
p++;
ch=*p;
if(presyn == 20||!isdigit(ch))
{
syn=22;
token[0]='+';
token[1]='\0';
p--;
return;
}
}
if(ch=='-')
{
p++;
ch=*p;
if(presyn == 20||!isdigit(ch))
{
syn=23;
token[0]='-';
token[1]='\0';
p--;
return;
}
flag=-1;
}
while(isdigit(ch))
{
integer = (ch - '0') + 10 * integer;
p++;
ch = *p;
}
sum = integer;
if(ch == '.')
{
p++;
ch = *p;
if(isdigit(ch))
{
int n = 0;
while(isdigit(ch))
{
n++;
decimal = decimal * 10 + ch - '0';
p++;
ch = *p;
}
for(i = 0; i < n; i ++)
decimal /= 10;
sum += decimal;
if(ch == 'e'||ch == 'E')
{
p++;
ch = *p;
if(ch == '+' || ch == '-')
{
if(ch == '+')
expMark = 1;
else
expMark = -1;
p++;
ch = *p;
if(isdigit(ch))
{
while(isdigit(ch))
{
exp = exp * 10 + ch - '0';
p++;
ch = *p;
}
p--;
syn = 20;
}
else
{
p--;
syn = -1;
}
}
else if(isdigit(ch))
{
while(isdigit(ch))
{
exp = exp * 10 + ch - '0';
p++;
ch = *p;
}
p--;
syn = 20;
}
else
{
p--;
syn = -1;
}
}
else
{
p--;
syn = 20;
}
}
else
{
p--;
syn = -1;
}
}
else if(ch == 'e'||ch =='E')
{
p++;
ch = *p;
if(ch == '+' || ch == '-')
{
if(ch == '+')
expMark = 1;
else
expMark = -1;
p++;
ch = *p;
if(isdigit(ch))
{
while(isdigit(ch))
{
exp = exp * 10 + ch - '0';
p++;
ch = *p;
}
p--;
syn = 20;
}
else
{
p--;
syn = -1;
}
}
else if(isdigit(ch))
{
while(isdigit(ch))
{
exp = exp * 10 + ch - '0';
p++;
ch = *p;
}
p--;
syn = 20;
}
else
{
p--;
syn = -1;
}
}
else
{
p--;
syn = 20;
}
return;
}
switch (ch) //第三部分:其它单词的识别
{
case '<':
token[m++]=ch;
p++;
ch=*p;
if(ch=='=') // <=
{
syn=35;
token[m++]=ch;
return;
}
syn=34;
token[m]='\0';
p--;
return;
case '>':
token[m++]=ch;
p++;
ch=*p;
if(ch=='=') //>=
{
syn=33;
token[m++]=ch;
return;
}
syn=32;
token[m]='\0';
p--;
return;
case '*':
syn=24;
token[0]=ch;
token[1]='\0';
//p++;
return;
case '/':
syn=25;
token[0]=ch;
token[1]='\0';
//p++;
return;
case '=':
token[m++]=ch;
p++;
ch=*p;
if(ch=='=')
{
syn=36;
token[m++]=ch;
return;
}
syn=21;
token[m]='\0';
p--;
return;
case '!' :
token[m++]=ch;
p++;
ch=*p;
if(ch!='=')
{
syn=-1;
p--;
return;
}
syn=37;
token[m++]='=';
token[m]='\0';
return;
case '(':
syn=26;
token[0]=ch;
token[1]='\0';
//p++;
return;
case ')':
syn=27;
token[0]=ch;
token[1]='\0';
//p++;
return;
case '{' :
syn=28;
token[0]='{';
token[1]='\0';
return;
case '}' :
syn=29;
token[0]='}';
token[1]='\0';
return;
case ',' :
syn=30;
token[0]=',';
token[1]='\0';
return;
case ';' :
syn=31;
token[0]=';';
token[1]='\0';
return;
case '\0' :
syn=1000;
token[0]=ch;
token[1]='\0';
return;
case '#' :
syn=0;
token[0]='#';
token[1]='\0';
return;
default:
syn=-1;
//p++;
return;
}
}
void expression()
{
term();
while(syn == 22 || syn == 23)
{
scan();
printWord();
term();
}
}
void term()
{
factor();
while(syn == 24 || syn == 25)
{
scan();
printWord();
factor();
}
}
void factor()
{
if(syn == 10 || syn == 20)
{
scan();
printWord();
}
else if(syn == 26)
{
scan();
printWord();
expression();
if(syn == 27)
{
scan();
printWord();
}
else
{
printf(" ')'错误\n");
k = 1;
}
}
else
{
printf(" '('错误\n");
k = 1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -