📄 pascal.cpp
字号:
#include<iostream.h>
#include<stdio.h>
#include<stdlib.h> //输出文件的头文件
#include<string.h>
#include<ctype.h> //漏掉注释符的头文件
const long stakmax=10000; //定义栈的最大长度
int hang; //标志
char Ischeck[]={' ','\n','+','-','*','(',')','{','}',
';','=','\"','%',',','&','[',']','!','#',':','\\','<','>','\'','/'}; //字符数组,用来存放标号界符共26个
const char keyword[][20]={"int","void","if",
"char","bool","break","case",
"catch","const","for","else",
"continue","class","while",
"do","goto","float","double",
"long","switch","friend","static",
"public","private","protected",
"return","struct","signed","array","program"};
//2维字符数组用来存放关键字共30个
struct stack //定义一个栈结构
{
char stak[stakmax]; //栈的大小为stakmaxsize
int top;
};
bool isCheck(const char& ch) //判别字符是否为标点符号
{
for(int i=0;i<29;i++)
if(ch==Ischeck[i])
return true;
return false;
}
void initstak(stack& s) //初使化栈
{
s.top=-1;
}
void clearstak(stack& s) //清空栈
{
s.top=-1;
}
void push(stack& s,const char& item) //字符入栈
{
if(s.top==stakmax-1) //如果栈满则输出'溢出'
{
cerr<<"溢出了"<<endl;
exit(1);
}
else
s.top++; //栈不满,栈头指针top增1,字符入栈
s.stak[s.top]=item;
}
bool isKeyword(stack& s) //判别是否为关键字
{
for(int i=0;i<30;i++)
if(!strcmp(s.stak,keyword[i])) //strcmp字符比较函数
return true;
return false;
}
void printout(stack& s) //判别字符是'关键字'还是'标识符'
{
if(isKeyword(s))
cout<<"("<< 1 <<","<<s.stak<<")"<< endl;//是关键字则用1表示
else
{
cout<<"("<< 2 <<","<<s.stak<<")"<< endl;//是标识符则用2表示
}
}
void digitpush(stack& s,const char& item) //数字进栈
{
if(s.top==stakmax-1) //栈满
{
cerr<<"溢出了"<<endl;
exit(1);
}
s.top++; //栈不满,栈头指针top增1,字符入栈
s.stak[s.top]=item;
}
void Getchar(FILE *fp,char& ch) //从指定文件取字符
{
ch=fgetc(fp); //fgetc()从指定的文件读入一个字符,该文件必须是以读或读写的方式打开的
if(ch=='\n') //如果ch='\n',则ren增1,ren为一个标号,当出错时用来指出出错位置所在行
hang++;
if(feof(fp)) //feof()若到文件尾,函数值为"真"
{
fclose(fp); //fclose() 关闭文件
getchar(); //getchar()函数返回stdin中的下一个字符.如果达到文件尾,getchar()返回EOF.如果遇到错误,也返回EOF.
exit(1);
}
}
void digitprint(stack& s) //输出数字函数
{
cout<<"数字:"<<s.stak<<endl;
}
void check(char *fname)
{
FILE *fp;
bool watch=false,checked=true; //设立watch,checked,ren的初值
hang=1;
if((fp=fopen(fname,"r"))==NULL) //判断能否打开文件,文件以读的方式打开
{
cerr<<"文件"<<"\'"<<fname<<"\'"<<"找不到"<<endl;
getchar();
exit(1);
}
stack a; //声明变量,函数部分
initstak(a);
char ch;
Getchar(fp,ch);
while(!feof(fp))
{
if(ch==' '||ch=='\n')
{
Getchar(fp,ch);
checked=true;
continue;
}
else if(checked && isalpha(ch)) //判断是否为字母,是字母返回1,否则返回0,checked查看上次有没有输入错误
{
while(isalnum(ch)) //判断是否是字母和数字的组成,是返回1,否则返回0
{
if(isCheck(ch))
break;
push(a,ch); //字符入栈
Getchar(fp,ch); //从栈中取字符
}
if(isCheck(ch))
{
push(a,'\0'); //'\0'代表空操作
printout(a); //输出栈中字符
clearstak(a); //清空栈
}
else
{
cout<<"错误位置"<<hang<<endl; //出错处理
checked=false;
clearstak(a);
continue;
}
}
else if(isdigit(ch) && checked)//判断是否为数字。是返回1,否则返回0,checked表示检查
//上次输入有没有错误
{
while(isdigit(ch)||ch=='.')
{
if(ch=='.')
watch=true;
if(isCheck(ch))
break;
digitpush(a,ch); //数字入栈
Getchar(fp,ch); //从栈中取数字
}
if(isCheck(ch))
{
if(watch) //如果watch 为真,则输出浮点型数
{
cout<<"float";
watch=false; //重新将watch 置为false
digitpush(a,'\0');
digitprint(a);
clearstak(a);
}
else
{
cout<<"int";//如果watch 为假则输出整数
digitpush(a,'\0');
digitprint(a);
clearstak(a);
}
}
else //出错处理
{
cout<<"有错误"<<hang<<endl;
checked=false; //重新将watch 置为false
clearstak(a);
continue;
}
}
else if(checked) //关系运算符的识别用3表示,如果checked 为真则执行以下语句
{
switch(ch)
{
case'!': Getchar(fp,ch);//函数Getchar(fp,ch)的功能是从文件fp中取字符
if(ch=='=')
{
cout<<"("<< 3 <<","<<"!="<<")"<< endl;
Getchar(fp,ch);
checked=true;
break;
}
else
{
cout<<"("<< 3 <<","<<"!"<<")"<< endl;
checked=true;
break;
}
case'=': Getchar(fp,ch);
if(ch=='=')
{
cout<<"("<< 3 <<","<<"=="<<")"<< endl;
Getchar(fp,ch);
checked=true;
break;
}
else
{
cout<<"("<< 3 <<","<<"="<<")"<< endl;
checked=true;
break;
}
case'+': Getchar(fp,ch);
if(ch=='=')
{
cout<<"("<< 3 <<","<<"+="<<")"<< endl;
Getchar(fp,ch);
checked=true;break;
}
else if(ch=='+')
{
cout<<"("<< 3 <<","<<"++"<<")"<< endl;
Getchar(fp,ch);checked=true;
break;
}
else
{
cout<<"("<< 3 <<","<<"+"<<")"<< endl;
checked=true;break;
}
case'*':Getchar(fp,ch);
if(ch=='=')
{
cout<<"("<< 3 <<","<<"*="<<")"<< endl;
Getchar(fp,ch);checked=true;
break;
}
else
{
cout<<"("<< 3 <<","<<"*"<<")"<< endl;
checked=true;break;
}
case'/': cout<<"("<< 3 <<","<<"/"<<")"<< endl;
Getchar(fp,ch);checked=true;
break;
case'-': Getchar(fp,ch);
if(ch=='=')
{
cout<<"("<< 3 <<","<<"-="<<")"<< endl;
Getchar(fp,ch);checked=true;
break;
}
else if(ch=='-')
{
cout<<"("<< 3 <<","<<"--"<<")"<< endl;
Getchar(fp,ch);
checked=true;
break;
}
else
{
cout<<"("<< 3 <<","<<"-"<<")"<< endl;
checked=true;
break;
}
case'>':
Getchar(fp,ch);
if(ch=='=')
{
cout<<"("<< 3 <<","<<">="<<")"<< endl;
Getchar(fp,ch);
checked=true;
break;
}
else
{
cout<<"("<< 3 <<","<<">"<<")"<< endl;
checked=true;
break;
}
case'<':
Getchar(fp,ch);
if(ch=='=')
{
cout<<"("<< 3 <<","<<"<="<<")"<< endl;
Getchar(fp,ch);
checked=true;
break;
}
else
{
cout<<"("<< 3 <<","<<"<"<<")"<< endl;
checked=true;
break;
}
case')':
cout<<"("<<4<<","<<")"<<")"<<endl;
Getchar(fp,ch);
checked=true;
break;
case'[':
cout<<"("<<4<<","<<"["<<")"<<endl;
Getchar(fp,ch);
checked=true;
break;
case'(':
cout<<"("<<4<<","<<"("<<")"<<endl;//界符用4表示
Getchar(fp,ch);
checked=true;
break;
case'}':
cout<<"("<<4<<","<<"}"<<")"<<endl;
Getchar(fp,ch);
checked=true;
break;
case']':
cout<<"("<<4<<","<<"]"<<")"<<endl;
Getchar(fp,ch);
checked=true;
break;
case';':
cout<<"("<<4<<","<<";"<<")"<<endl;
Getchar(fp,ch);
checked=true;
break;
case'\'':
cout<<"("<<4<<","<<"\\"<<")"<<endl;
Getchar(fp,ch);
checked=true;
break;
case',':
cout<<"("<<4<<","<<","<<")"<<endl;
Getchar(fp,ch);
checked=true;
break;
case'%':
cout<<"("<<4<<","<<"%"<<")"<<endl;
Getchar(fp,ch);
checked=true;
break;
case'#':
cout<<"("<<4<<","<<"("<<"#"<<endl;
Getchar(fp,ch);
checked=true;
break;
case'&':
cout<<"("<<4<<","<<"("<<"&"<<endl;
Getchar(fp,ch);
checked=true;
break;
case':':
cout<<"("<<4<<","<<"("<<":"<<endl;
Getchar(fp,ch);
checked=true;
break;
case'\"':
cout<<"("<<4<<","<<"\""<<")"<<endl;
Getchar(fp,ch);
checked=true;
break;
case'\n':break;
case'\\':
Getchar(fp,ch);
if(ch=='n')
{
cout<<"("<<4<<","<<"\\n"<<")"<<endl;
Getchar(fp,ch);
checked=true;
break;
}
else
{
cout<<"("<<4<<","<<"\\"<<")"<<endl;
checked=true;
break;
}
case' ': break;
default:
cout<<"错误在第"<<hang<<"行"<<endl;
checked=false;
Getchar(fp,ch);
}
}
}
}
void main()
{
char filenames[100];
cout<<" \n ";
cout<<" Pascal词法分析器"<<endl;
cout<<" "<<endl;
cout<<" "<<endl;
cout<<"请输入你所要分析的程序所在的路径(文件名用英文或数字命名):"<<endl;
cin>>filenames;
cout<<"\n 词法分析结果 \n"<<endl;
cout<<"单词符号"<<" "<<"单词符号的属性值"<<endl;
check(filenames);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -