TEST语言——词法分析

1.1 TEST 语言概述
TEST 语言的程序结构简单,整个程序相当于 C 语言的函数体,即由一对花
括号括起的语句序列,没有函数,没有数组;声明语句、表达式语句以及控制
语句和 C 语言类似。数据类型只有整型,一个声明语句只能声明一个变量;表
达式只有算术表达式和布尔表达式两种形式,其中算术表达式为整型变量和整
型常数的四则运算组合,布尔表达式为两个算术表达式的比较运算;控制语句
只有 if、while 和 for 三种语句;支持复合语句;read 语句和 write 语句实现
输入输出;注释仅为多行注释/* …… /。 1.2 TEST 语言的词法规则
1、标识符:字母打头,后接任意字母或数字。其中保留字为标识符的子集,包
括:if, else, for, while, int, write, read。
3、无符号整数:由数字组成,但最高位不能为 0,允许一位的 0。
4、分界符:(、)、;、{、}
5、运算符:+、-、
、/、=、<、>、>=、<=、!=、==
6、注释符:/* */
1.3 TEST 语言的语法规则

  1. → {<declaration_list><statement_list>} 2) <declaration_list> → <declaration_list><declaration_stat> | ε 3) <declaration_stat> → int ID;
  2. <statement_list> → <statement_list>| ε 5) → <if_stat>|<while_stat>|<for_stat>|<read_stat> |<write_stat>|<compound_stat> |<assignment_stat>|; 6) <if_stat> → if (<bool_expression >) | if (<bool_expression>) else < statement > 7) <while_stat> → while (<bool_expression>) < statement > 8) <for_stat> → for (<assignment_expression>; <bool_expression>; <assignment_ expression >) 9) <write_stat> → write < arithmetic_expression >; 10) <read_stat> → read ID; 11) <compound_stat> → {<statement_list>} 12) <assignment_expression> → ID=<arithmetic_expression> 13) <assignment_stat> →<assignment_expression>; 14) <bool_expression>→<arithmetic_expression> > <arithmetic_expression> |<arithmetic_expression> < <arithmetic_expression> |<arithmetic_expression> >= <arithmetic_expression> |<arithmetic_expression> <= <arithmetic_expression> |<arithmetic_expression> == <arithmetic_expression> |<arithmetic_expression> != <arithmetic_expression> 15) <arithmetic_expression> → <arithmetic_expression>+ |< arithmetic_expression>- |< term > 16) < term > → < term >*|< term >/|< factor > 17) < factor > → (<arithmetic_expression>)|ID|NUM
    2 目标机器

3.1.4 实验内容
1、根据 TEST 语言的词法规则,分别写出每条词法规则对应的正则表达式; 2、将每一个正则表达式转换为 NFA; 3、将多个 NFA 合并后进行确定化并化简; 4、参阅在实验语言部分给出的 TEST 语言语法规则,确定单词分类、单词输出方
案; 5、根据最小的 DFA 编写词法分析程序; 6、对下面的 TEST 语言源程序进行词法分析,将合法单词存入 lex.txt,并报告 词法错误及其位置。注:不能修改以下源程序。

{
    
     
/*This a test program.*/ 
int abc;
int 123; 
int A$@; 
int 2a; 
int a2; 
read n;
n = 012345;
for (i=1;i<=n; i= i+1) 
{
    
      
abc=abc+i; 
} 
if(i!=n) n = n+i; 
if (!n) b = b+c; 
/*The loop ended 
write abc; 
}

3.1.5 实验报告要求
1、实验设计
(1)DFA 设计过程:给出每条词法规则对应的正则表达式、由正则表达式构
造的 NFA、合并后的 NFA、确定化后的 DFA、最小化后的 DFA。
(2)词法分析结果的输出形式:给出单词类别。
2、实验过程 (1)简述完成实验的步骤。 (2)实验调试记录:实验过程中遇到的问题,对该问题进行描述,分析其产 生的原因,提出解决方案,给出最后的解决结果。 3、实验结果
(1)给出词法分析程序识别的单词。
(2)给出词法分析程序识别出的词法错误。
4、讨论与分析
(1)通过实验对词法分析相关知识点的理解。
(2)回答实验思考部分提出的问题。
3.1.6 实验思考
1、设计的词法分析程序是否满足最长匹配原则?如果满足请给出实现方案。如
果不满足请给出改进方案。
2、给出单词分类方案,并说明理由。
3、简述构建词法分析程序一般步骤。

词法分析程序:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<stdio.h>
#include<ctype.h>
using namespace std;
#define keywordSum 8
char *keyword[keywordSum] = {
    
     "if", "else", "for", "while", "do", "int", "read", "write" };
//单分界符
char singleword[50] = "+-*{}();,:";
//双分界符
char doubleword[10] = "<>=!";
char Scanin[300] = "test.txt";
char Scanout[300] = "testout.txt";
int line = 1;
FILE *fin, *fout;
int TESTscan()
{
    
    
	char ch, token[40]; //ch读入字符 token保存识别单词
	int es = 0, j, n;
	if ((fin = fopen(Scanin, "r")) == NULL)
	{
    
    
		cout << "输入文件有误";
		return 1;
	}
	if ((fout = fopen(Scanout, "w")) == NULL)
	{
    
    
		cout << "输出文件有误";
		return 2;
	}
	ch = getc(fin);
	while (ch != EOF)
	{
    
    
		while (ch == ' ' || ch == '\n' || ch == '\t')
		{
    
    
			if (ch == '\n'){
    
    
				line++;
			}
			ch = getc(fin);
		}
		if (isalpha(ch))
		{
    
    
			token[0] = ch;
			j = 1;
			ch = getc(fin);
			while (isalnum(ch))
			{
    
    
				token[j++] = ch;
				ch = getc(fin);
			}
			token[j] = '\0';
			n = 0;
			while ((n < keywordSum) && strcmp(token, keyword[n]))n++;
			if (n >= keywordSum)
			{
    
    
				fprintf(fout, "%s\t%s\n", "ID", token);

			}
			else
			{
    
    
				fprintf(fout, "%s\t%s\n", token, token);
			}

		}
		else if (isdigit(ch))
		{
    
    
			token[0] = ch;
			j = 1;
			ch = getc(fin);
			while (isdigit(ch))
			{
    
    
				token[j++] = ch;
				ch = getc(fin);
			}
			token[j] = '\0';
			fprintf(fout, "%s\t%s\n", "NUM", token);

		}
		else if (strchr(singleword, ch)>0)
		{
    
    
			token[0] = ch;
			token[1] = '\0';
			ch = getc(fin);
			fprintf(fout, "%s\t%s\n", token, token);
		}
		else if (strchr(doubleword, ch)>0)
		{
    
    
			token[0] = ch;
			ch = getc(fin);
			if (ch == '=')
			{
    
    
				token[1] = ch;
				token[2] = '\0';
				ch = getc(fin);
			}
			else
			{
    
    
				token[1] = '\0';

			}
			fprintf(fout, "%s\t%s\n", token, token);

		}
		else if (ch == '/')
		{
    
    
			ch = getc(fin);
			if (ch == '*')
			{
    
    
				char ch1;
				ch1 = getc(fin);
				do
				{
    
    
					ch = ch1;
					ch1 = getc(fin);
				} while ((ch != '*' || ch1 != '/') && ch1 != EOF);
				ch = getc(fin);
			}
			else
			{
    
    
				token[0] = '/';
				token[1] = '\0';
				fprintf(fout, "%s\t%s\n", token, token);
			}
		}
		else
		{
    
    
			token[0] = ch;
			token[1] = '\0';
			ch = getc(fin);
			es = 3;
			printf("ERROR AT LINE%d: %s\n",line, &token);
		}

	}
	fclose(fin);
	fclose(fout);
	return(es);
}
int main()
{
    
    
	int es = 0;
	es = TESTscan();
	if (es > 0)cout << "词法分析有错,编译停止!\n";
	else cout << "词法分析成功!\n";
	system("pause");
	return 0;
}

结果:

{
    
    	{
    
    
int	int
ID	abc
;	;
int	int
NUM	123
;	;
int	int
ID	A
;	;
int	int
NUM	2
ID	a
;	;
int	int
ID	a2
;	;
read	read
ID	n
;	;
ID	n
=	=
NUM	012345
;	;
for	for
(	(
ID	i
=	=
NUM	1
;	;
ID	i
<=	<=
ID	n
;	;
ID	i
=	=
ID	i
+	+
NUM	1
)	)
{
    
    	{
    
    
ID	abc
=	=
ID	abc
+	+
ID	i
;	;
}	}
if	if
(	(
ID	i
!=	!=
ID	n
)	)
ID	n
=	=
ID	n
+	+
ID	i
;	;
if	if
(	(
!	!
ID	n
)	)
ID	b
=	=
ID	b
+	+
ID	c
;	;

猜你喜欢

转载自blog.csdn.net/qq_43325582/article/details/110688868
今日推荐