simple.cpp
来自「基于simple语言的简单词法分析器源代码」· C++ 代码 · 共 225 行
CPP
225 行
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <iomanip>
using namespace std;
void main()
{
cout<<" ***********************************\n";
cout<<" 欢迎使用SAMPLE语言的词法分析器\n";
cout<<" ***********************************\n\n";
cout<<" 姓名:刘达魁 班级:05计算机科学与技术(1)班 学号:200530754034\n\n\n";
string key[35]={"and","array","begin","bool","call","case","char","constant","dim","do","else","end",
"false","for","if","input","integer","not","of","or","output","procedure","program",
"read","real","repeat","set","stop","then","to","true","until","var","while","write"};
string limit[22]={"(",")","*","*/","+",",","-",".","..","/","/*",":",
":=",";","<","<=","<>","=",">",">=","[","]"};
fstream file;
char fileName[20];
cout<<"请输入待检测的文件名:\n";
cin>>fileName;
cout<<"\n分析结果为:\n";
file.open(fileName,ios::in); //打开文件
if(! file)
{
cerr<<"文件不能被打开!"<<endl;
abort();
}
char buffer[20];
char* s=new char [100];
int line=0;//记录已从文件中读取的行数
char* check[50]; //存储检测过的标志符,整数,字符常数
int e=0; //记录已存标志符,整数,字符常数的个数
for(int x=0;x<50;x++) //初始化check数组
{
check[x]="^_^";
}
/******************************判断模块******************************/
while(! file.eof())
{
line++;
file.getline(s,100);
int n=strlen(s);
//cout<<n<<endl;
for(int j=0;j<n;j++)
{
int k=0;
if(((s[j]>='A')&&(s[j]<='Z'))||((s[j]>='a')&&(s[j]<='z')))//字母开头
{
while(((s[j]>='A')&&(s[j]<='Z'))||((s[j]>='a')&&(s[j]<='z'))||((s[j]>='0')&&(s[j]<='9')))
{
buffer[k++]=s[j]; //将输入字符逐个放入数组buffer中
j++;
}
buffer[k++]='\0';
char* array=new char;
strcpy(array,buffer);
int p=1;
for(int i=0; i<35; i++)
{
if(!key[i].compare(array)) //判断是否为关健字
{
cout<<setw(10)<<"("<<i+1<<",-)"<<'\t';
p++;
}
}
int d=0; //标记d=0时,向check[]中插入新的标志符,整数,字符常数
if(p==1)
{
for(int z=0;z<50;z++)
{
if(!strcmp(check[z],array))
{
cout<<setw(13)<<"(36,"<<z+1<<")"<<'\t';
d++;
}
}
if(d==0)
{
check[e++]=array;
cout<<setw(13)<<"(36,"<<e<<")"<<'\t';
}
}
j--;//退一格
}
else if(s[j]>='0'&&s[j]<='9') //数字开头
{
while(s[j]>='0'&&s[j]<='9')
{
buffer[k++]=s[j];
j++;
}
buffer[k++]='\0';
char* array=new char;
strcpy(array,buffer);
int d=0; //标记,同上
for(int z=0;z<50;z++)
{
if(!strcmp(check[z],array))
{
cout<<setw(13)<<"(37,"<<z+1<<")"<<'\t';
d++;
}
}
if(d==0)
{
check[e++]=array;
cout<<setw(13)<<"(37,"<<e<<")"<<'\t';
}
j--;
}
else if(s[j]=='\'') //单引号开头
{
int q=0;//q=0时,字符常数缺右边的单引号
int m1=j;
for(m1++;m1<n;m1++) //检测单引号是否匹配
{
if(s[m1]=='\'')
{
for(int z=j;z<=m1;z++)
{
buffer[k++]=s[z];
z++;
}
buffer[k++]='\0';
char* array=new char;
strcpy(array,buffer);
int d=0; //标记,同上
for(z=0;z<50;z++)
{
if(!strcmp(check[z],array))
{
cout<<setw(13)<<"(38,"<<z+1<<")"<<'\t';
d++;
}
}
if(d==0)
{
check[e++]=array;
cout<<setw(13)<<"(38,"<<e<<")"<<'\t';
}
q++;
j=m1;
}
}
if(q==0) cout<<"第"<<line<<"行字符常数缺右边的单引号!";
}
else if(s[j]=='/'&&s[j+1]=='*') //检测注释符是否匹配
{
int d=0;//d=0时,行注释部分缺右边界
int m=j;
for(m=m+2;m<n;m++)
{
if(s[m]=='*'&&s[m+1]=='/') d=1;
j=m+1;
}
if (d==0) cout<<"第"<<line<<"行行注释部分缺右边界!";
}
else if(s[j]=='.'||s[j]==':'||s[j]=='<'||s[j]=='>') //符号. : < > 开头
{
if(s[j+1]!='.' && s[j+1]!='=' && s[j+1]!='>') //单符号
{
buffer[k++]=s[j];
buffer[k++]='\0';
char* array=new char;
strcpy(array,buffer);
for(int b=0;b<22;b++)
{
if(!limit[b].compare(array))
{
cout<<setw(10)<<"("<<b+39<<",-)"<<'\t';
}
}
}
else //双符号
{
buffer[k++]=s[j++];
buffer[k++]=s[j++];
buffer[k++]='\0';
char* array=new char;
strcpy(array,buffer);
for(int b=0;b<22;b++)
{
if(!limit[b].compare(array))
{
cout<<setw(10)<<"("<<b+39<<",-)"<<'\t';
}
}
j--;
}
}
else if(s[j]==' ');
else //其他界符
{
buffer[k++]=s[j];
buffer[k++]='\0';
char* array=new char;
strcpy(array,buffer);
int pp=0;//标记
for(int b=0;b<22;b++)
{
if(!limit[b].compare(array))
{
cout<<setw(10)<<"("<<b+39<<",-)"<<'\t';
pp++;
}
}
if(pp==0) cout<<"第"<<line<<"行中存在非法字符!";
}
}
}
file.close(); //关闭文件
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?