目录
0 实验目的:
编写一个程序可以从文本文件中识别出进制、标识符种类等,加深对进制,标识符组成的了解。
1 实验内容:
根据标识符,实数以及进制数特点,编写识别出它们的分析器,以文本文件输入,控制台输出识别出来的相关内容。
2 实验思路:
- 根据标识符后缀的特点以及进制转换的自动机写出识别标识符以及进制数的相关函数。
- 我依然将程序分成五个部分,判断关键字函数,判断字母函数,判断数字函数(包括识别相应的进制数),核心子程序(语法分析程序),主函数。
- 单独强调一下识别进制数的部分,首先判断第一个数字是否为1-9,如果可以确定为10进制。如果第一个数字是0,判断后面是否还有数字,且数字范围为0-7,可以确定为8进制。如果后面为X而同时X后面为0-9,a-f我们可以确定为16进制。
- 函数调用核心子程序(语法分析程序),并按照(种别码,单词字符,单词属性)的形式输出,结束程序。
注意:需要强调的是,此次实验注重进制的识别,以及标识符后缀的识别。也需要注意的是此次实验为文件输入;
3 实验代码:
#include <bits/stdc++.h>
using namespace std;
int isDigit();
int isAlpha();
int isKey();
void scan(int &attr, int &i, char s[]);
char iskey[10][50] = {"begin","if", "then", "while", "do", "end","int","char","main","return"};
char token[50];
char ken[50];
//主函数
int main()
{
FILE*in;
int j=0;
char s[100],sr[100],data[10];
char str [100][100];
cout << "从文本文件中读取单词字符段" << endl;
int flag=0;
if((in=fopen("E:\\data.txt","r"))==NULL){
printf("无法打开此文件\n");
return 0;
}
while(fgets(str[j],100,in)!=NULL){
cout<<str[j];
}
fseek(in,0,SEEK_SET);
printf("\n");
cout << "[ "<< "种别码" <<" "<< "单词符号" <<" "<<"单词属性"<<" ]"<< endl;
while(fgets(str[j],100,in)!=NULL){
strcpy(s,str[j]);
int i = 0;
int attr;
while (i <strlen(s)-1)
{
scan(attr, i, s);
cout << "[ "<< attr <<" \t"<< token <<" \t "<<ken<<"\t"<<" ]"<< endl;
}
j++;
}
cout << "[ "<< 70 <<" \t"<< "}"<<"\t"<<"界符"<<"\t"<<" ]"<< endl;
fclose(in);
return 0;
}
int isAlpha(char ch)//判断是不是字母
{
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
return 1;
else
return 0;
}
int isKey(char s[])//判断关键字
{
for (int i = 0; i < 10; i++)
{
if (strcmp(s, iskey[i]) == 0)
{
strcpy(ken,"保留字");
return i + 1;
}
}
return -1;
}
int isDigit(char ch)//判断是不是数字
{
if (ch >= '0' && ch <= '9')
return 1;
else
return 0;
}
void scan(int &attr, int &i, char s[])//核心子程序(语法分析程序)
{
int temp = 0;
if (s[i] == ' ')
i++;
if (isAlpha(s[i]))//开头是字母
{
while (isDigit(s[i]) || isAlpha(s[i]))
{
token[temp++] = s[i];
i++;
}
token[temp] = '\0';
attr = isKey(token);
if (attr == -1)
{
strcpy(ken,"id");
attr = 10;
}
}
else if (isDigit(s[i]))//开头是数字
{
if(s[i]=='0'){
if(s[i+1]=='x'){
while (isDigit(s[i])||s[i]=='.'||s[i]=='x')
{
token[temp++] = s[i];
i++;
}
token[temp] = '\0';
strcpy(ken,"16进制");
attr = 11;}else if(s[i+1]=='.'){
while (isDigit(s[i])||s[i]=='.')
{
token[temp++] = s[i];
i++;
}
token[temp] = '\0';
strcpy(ken,"10进制");
attr = 11;
}else {
while (isDigit(s[i])||s[i]=='.')
{
token[temp++] = s[i];
i++;
}
token[temp] = '\0';
strcpy(ken,"8进制");
attr = 11;
}
}else{
while (isDigit(s[i])||s[i]=='.')
{
token[temp++] = s[i];
i++;
}
token[temp] = '\0';
strcpy(ken,"10进制");
attr = 11;
}
}
else//如果是运算符或者界符
{
switch (s[i])
{
case '+':
strcpy(ken,"运算符");
attr = 13;
token[0] = s[i];
token[1] = '\0';
break;
case '-':
strcpy(ken,"运算符");
attr = 14;
token[0] = s[i];
token[1] = '\0';
break;
case '*':
strcpy(ken,"运算符");
attr = 15;
token[0] = s[i];
token[1] = '\0';
break;
case '/':
strcpy(ken,"运算符");
attr = 16;
token[0] = s[i];
token[1] = '\0';
break;
case '=':
strcpy(ken,"运算符");
attr = 25;
token[0] = s[i];
token[1] = '\0';
break;
case ';':
strcpy(ken,"界符");
attr = 26;
token[0] = s[i];
token[1] = '\0';
break;
case '(':
strcpy(ken,"界符");
attr = 27;
token[0] = s[i];
token[1] = '\0';
break;
case ')':
strcpy(ken,"界符");
attr = 28;
token[0] = s[i];
token[1] = '\0';
break;
case '#':
strcpy(ken,"界符");
attr = 0;
token[0] = s[i];
token[1] = '\0';
break;
case '{':
strcpy(ken,"界符");
attr = 69;
token[0] = s[i];
token[1] = '\0';
break;
case '}':
strcpy(ken,"界符");
attr = 70;
token[0] = s[i];
token[1] = '\0';
break;
case ',':
strcpy(ken,"界符");
attr = 71;
token[0] = s[i];
token[1] = '\0';
break;
}
if (s[i] == ':')
{
token[temp++] = s[i];
if (s[i + 1] == '=')
{
i++;
token[temp++] = s[i];
strcpy(ken,"运算符");
attr = 18;
}
else
{
strcpy(ken,"界符");
attr = 17;
}
token[temp] = '\0';
}
if (s[i] == '<')
{
token[temp++] = s[i];
if (s[i + 1] == '>')
{
i++;
token[temp++] = s[i];
strcpy(ken,"运算符");
attr = 21;
}
else if (s[i + 1] == '=')
{
i++;
token[temp++] = s[i];
strcpy(ken,"运算符");
attr = 22;
}
else
{
strcpy(ken,"运算符");
attr = 20;
}
token[temp] = '\0';
}
if (s[i] == '>')
{
token[temp++] = s[i];
if (s[i + 1] == '=')
{
i++;
token[temp++] = s[i];
strcpy(ken,"运算符");
attr = 24;
}
else
{
strcpy(ken,"运算符");
attr = 23;
}
token[temp] = '\0';
}
i++;
}
}
4 实验结果:
5 实验总结:
这个实验比较好实现,也是词法分析器的一部分内容,可能你找的与此实验的要求不相同,你可以稍微改一下,需要探讨与我私信。
6 实验程序以及实验报告下载链接: