编译原理——进制、标识符识别(C/C++代码实现)

目录

0 实验目的:

1 实验内容:

2 实验思路:

3 实验代码:

4 实验结果:

5 实验总结:

6 实验程序以及实验报告下载链接:


0 实验目的:

编写一个程序可以从文本文件中识别出进制、标识符种类等,加深对进制,标识符组成的了解。


1 实验内容:

根据标识符,实数以及进制数特点,编写识别出它们的分析器,以文本文件输入,控制台输出识别出来的相关内容。


2 实验思路:

  1. 根据标识符后缀的特点以及进制转换的自动机写出识别标识符以及进制数的相关函数。
  2. 我依然将程序分成五个部分,判断关键字函数,判断字母函数,判断数字函数(包括识别相应的进制数),核心子程序(语法分析程序),主函数。
  3. 单独强调一下识别进制数的部分,首先判断第一个数字是否为1-9,如果可以确定为10进制。如果第一个数字是0,判断后面是否还有数字,且数字范围为0-7,可以确定为8进制。如果后面为X而同时X后面为0-9,a-f我们可以确定为16进制。
  4. 函数调用核心子程序(语法分析程序),并按照(种别码,单词字符,单词属性)的形式输出,结束程序。

                注意:需要强调的是,此次实验注重进制的识别,以及标识符后缀的识别。也需要注意的是此次实验为文件输入;


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 实验程序以及实验报告下载链接:

编译原理实验:包括实验一词法分析器,实验二进制分析,实验三语法分析器,实验四SLR语法分析器等其中含有实验报告,实验代码等等-C++文档类资源-CSDN文库icon-default.png?t=MBR7https://download.csdn.net/download/qq_58773908/87356376

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小航同学吖

制作不易,动动你的小手

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值