简单词法分析器的实现


title: 简单词法分析器的实现
date: 2018-10-08 23:15:26
updated: 2018-10-08 23:15:26
description: 简单词法分析器的实现_编译原理实现
categories: 必修
photo:
tags:

  • 编译原理
    music-id: 415793869
    password:
    math:

一.实验题目

用C或C++语言编写一个简单的词法分析程序,扫描C语言小子集的源程序,根据给定的词法规则,识别单词,填写相应的表。如果产生词法错误,则显示错误信息、位置,并试图从错误中恢复。简单的恢复方法是忽略该字符(或单词)重新开始扫描。

二.词法分析规则:

<标识符>::=<字母>
<标识符>::=<标识符><字母>
<标识符>::=<标识符><数字>
<无符号整数>::=<数字>
<无符号整数>::=<数字序列><数字>
<数字序列>::=<数字序列><数字>
<数字序列>::=<数字>
<字母>::=a|b|c|……|x|y|z
<数字>::=0|1|2|3|4|5|6|7|8|9

<加法运算符>::=+|-
<乘法运算符>::=*|/
<关系运算符>::=<|>|!=|>=|<=|==
<分界符>::=,|;|(|)|{|}
<保留字>::=main|int|if|else|while|do

三.实现任务

1.根据给定的词法规则,识别单词,填写相应的表。
2.忽略空白字符,注释
3.产生词法错误时,显示错误信息、位置,并试图从错误中恢复。

四.实现流程

1.读到空格则略过,读下一个字符;若读到的是字母,就再接着读,直到读到的既不是字母也不是数字也不是下划线,并将读到的写入到token数组;
2.若读到的是数字,直到读到的不是数字或小数点,将读到的写入到token数组;
3.若读到的是<|>|=,则再读入下一位,若为=,则该运算符为<=|>=|==,若为其他字符,则返回<|>|=的种别码;若读到的是/,则读下一位,若为*,则说明之后为注释内容,一直读入直到读入*,并判断下一位是否为/,若是则注释结束,不是继续往下一位读入;若读入\n,则行数加一,若读入的字符与以上都不匹配,则报错,并输出出错行数。
https://pic3.zhimg.com/80/v2-19496af106a27077884c55cf028f3518_hd.jpg

五.种别码:

单词符号 种别码 单词符号 种别码
# 0 + 18
Num 1 - 19
Letter 2 * 20
main 3 / 21
if 4 = 22
else 5 > 23
do 6 >= 24
while 7 < 25
for 8 <= 26
swtich 9 ; 27
case 10 " 28
int 11 ++ 29
double 12 30
float 13 /* 31
long 14 */ 32
void 15 { 33
( 16 } 34
) 17

六.代码实现

/*
author:Manson
date:10.08.2018
theme:
*/
#include<iostream> 
#include<cstring>
using namespace std;
typedef long long ll;
const int N = 1005;

const char keyWord[13][20] = {"main","if","else","do","while","for","switch",
"case","int","double","float","long","void"};
char token[12];
char in[105];
int cnt = 0,token_num = 0;
//读入代码 
void read(char *in){
	char ch;
	int i;
	for(i = 0;cin.get(ch) && ch!='#';i++){
		in[i] = ch;
	}
	in[i] = '#';
}

void init_token(){
	int i;
	for(i = 0;i < 12;i++){
		token[i] = NULL;
	}
}

int judge_token(){
	init_token();
	char ch = in[cnt++];
	while(ch == ' '){
		ch=in[cnt++];
	}
	token_num = 0;
	if((ch>='a' && ch <= 'z') || (ch >= 'A' &&ch <= 'Z')){
		//可能为标识符或者变量名 
		while((ch>='a' && ch <= 'z') || (ch >= 'A' &&ch <= 'Z') || (ch >= '0' && ch <= '9')){
			token[token_num++] = ch;
			ch = in[cnt++];
		}
		token[token_num++] = '\0';
		cnt--;
		for(int i = 0;i <13;i++){
			if(strcmp(token,keyWord[i]) == 0){
				return i;
			}
		}
		return 2;
	}
	//是数字 
	else if(ch >= '0' && ch <= '9'){
		while((ch >= '0'&& ch <= '9') || ch == '.'){
			token[token_num++] = ch;
			ch = in[cnt++];
		}
		cnt--;
		return 1;
	}
	else{
		token[token_num++] = ch;
		switch(ch){
			case '(': return 16;
			case ')': return 17;
			case '{': return 33;
			case '}': return 34;
			case '+':
				token[token_num++] = ch;
				ch = in[cnt++];
				if(ch == '+'){
					return 29;
				}
				else{
					cnt--;
					return 18;
				}
			case '-':
				token[token_num++] = ch;
				ch = in[cnt++];
				if(ch == '-'){
					return 30;
				}
				else{
					cnt--;
					return 19;
				}
			case '*':

				token[token_num++] = ch;
				ch = in[cnt++];
				if(ch == '/'){
					return 32;
				}
				else{
					cnt--;
					return 20;
				}
			case '/':

				token[token_num++] = ch;
				ch = in[cnt++];
				if(ch == '*'){
					return 31;
				}
				else{
					cnt--;
					return 21;
				}
			case '=':
				return 22;
			case '>':
				token[token_num++] = ch;
				ch = in[cnt++];
				if(ch == '='){
					return 24;
				}
				else{
					cnt--;
					return 23;
				}
			case '<':
				token_num = 0;
				token[token_num++] = ch;
				ch = in[cnt++];
				if(ch == '='){
					return 26;
				}
				else{
					cnt--;
					return 24;
				}
			case ';':
			return 27;
			case '"':
			return 28;
			case '\n':
				init_token();
				return -2;
			case '#':
				return 0;
				break;
			default:
				return -1;
				break;
		}
	}
}

void judge(){
	int order = 0,row = 0;
	int temp;
	do{
		temp = judge_token();
		switch(temp){
			case -1:
				cout<<"第 "<<row<<" 行出现错误."<<endl;
				break;
			//遇到换行则行数加 1 
			case -2:
				row++;
				break;
			default:
				cout<<"<"<<temp<<","<<token<<">"<<endl;
				break;
		}
	}while(temp!=0);
}

int main(){
	cout<<"enter your test code and use # to end the code:"<<endl;
	read(in);
	
	judge();
	
	return 0;
}
/*
for(int i = 0;i < max;i++){
	i = 3*i+2;
}#
int c1;
!6
!7#
*/

七.样例结果

Case1:
for(int i = 0;i < max;i++){
i = 3*i+2;
}#
Result1:

在这里插入图片描述

Case2:
int c1;
!6
!7#
Result2:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_36711003/article/details/82975586