词法分析程序的设计(编译原理实验一)

词法分析程序的设计(编译原理实验一)

一、实验内容

​ 编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。

二、实验要求

  1. 编写程序,识别如下单词符号

    标识符 <字母>(<字母>|<数字字符>)*

    十进制整数 0 | (1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)

    八进制整数 0(1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)*

    十六进制整数 0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)*

    运算符和界符 + - * / > < = ( ) ;

    关键字 if then else while do

  2. 以二元组形式输出单词<单词种类,单词属性>

    其中单词种类用整数表示:

    0:标识符

    1:十进制整数

    2:八进制整数

    3:十六进制整数

    运算符和界符,关键字采用一字一符,不编码

    其中单词属性表示如下:

    标识符,整数由于采用一类一符,属性用单词表示

    运算符和界符,关键字采用一字一符,属性为空

三、测试数据

输入数据:

​ 编辑一个文本文件program.txt,在文件中输入如下内容:

在这里插入图片描述

正确结果:

在这里插入图片描述

四、实验代码

//头文件
#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

//全局变量
string instr;//输入符号串  存放整个程序的字符串
int index;//当前输入符号读入字符的位置,字符指针,逐个读取instr,识别出一个一个单词
char character;//全局变量字符,存放index读取的字符
string token;//字符数组,存放已读入的字符序列,也即目前读取的单词


const int len = 10;
string Reserve[len];//保留字表


//要输出的二元组形式:<单词种类,单词属性>
struct Binary {
   
	Binary(string t, string v) {
   
		type = t;
		value = v;
	}
	string type;
	string value;
};

//构造关键字表的函数
void init_Reserve() {
   
	Reserve[0] = "if";
	Reserve[1] = "then";
	Reserve[2] = "else";
	Reserve[3] = "while";
	Reserve[4] = "do";
}

//读入一个字符
void getChar() {
   
	character = instr[index++];
}

//读入非空白字符
void getnbc() {
   
	while (character == ' ') {
   
		getChar();
	}
}

//连接字符串
void concat() {
   
	token = token + character;
}


//判断是否为字母
bool letter() {
   
	if ((character >= 'A' && character <= 'Z') || (character >= 'a' && character <= 'z'))
		return true;
	return false;
}


//判断是否为数字
bool digit() {
   
	if (character >= '0' && character <= '9')
		return true;
	return false;
}


//回退读取字符串的指针
void retract() {
   
	character = ' ';
	index--;
}	  


//判断标识符
bool isIdentifier() {
   	
	for (int i = 1; i < token.size(); i++) {
   
		if (!((token[i] >= '0' && token[i] <= '9') || (token[i
  • 14
    点赞
  • 103
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实验目的: 1.理解词法分析程序的基本原理和算法。 2.掌握Flex工具的使用方法。 3.掌握正则表达式的使用方法。 实验要求: 1.设计一个简单的词法分析程序能够识别出以下关键字:if, else, for, while, do, break, continue, return。 2.能够识别出整数、浮点数、标识符、运算符、界符等。 3.能够对输入的代码进行词法分析并输出结果。 实验过程: 1.安装Flex工具。 2.编写词法分析器的规则。 3.编写测试程序。 4.使用Flex工具生成词法分析器。 5.编译并运行测试程序实验步骤: 1.安装Flex工具。 在Ubuntu系统中,可以使用以下命令安装Flex工具: ``` sudo apt-get install flex ``` 2.编写词法分析器的规则。 在本实验中,我们需要识别出以下关键字: if, else, for, while, do, break, continue, return 可以使用以下正则表达式进行匹配: ``` "if" {return IF;} "else" {return ELSE;} "for" {return FOR;} "while" {return WHILE;} "do" {return DO;} "break" {return BREAK;} "continue" {return CONTINUE;} "return" {return RETURN;} ``` 我们还需要识别出整数和浮点数。可以使用以下正则表达式进行匹配: ``` [0-9]+ {yylval.num = atoi(yytext); return INT;} [0-9]+"."[0-9]+ {yylval.fnum = atof(yytext); return FLOAT;} ``` 其中,yylval是Flex工具自带的一个全局变量,用于存储识别出的标识符整数或浮点数的值。 我们还需要识别出运算符和界符。可以使用以下正则表达式进行匹配: ``` "+" {return ADD;} "-" {return SUB;} "*" {return MUL;} "/" {return DIV;} "%" {return MOD;} "=" {return ASSIGN;} ">" {return GT;} ">=" {return GE;} "<" {return LT;} "<=" {return LE;} "!=" {return NE;} "==" {return EQ;} ";" {return SEMICOLON;} "," {return COMMA;} "(" {return LPAREN;} ")" {return RPAREN;} "{" {return LBRACE;} "}" {return RBRACE;} ``` 最后,我们需要识别出标识符。可以使用以下正则表达式进行匹配: ``` [a-zA-Z][a-zA-Z0-9]* {yylval.id = strdup(yytext); return IDENTIFIER;} ``` 3.编写测试程序。 在本实验中,我们编写一个简单的测试程序,用于测试词法分析器是否正确。 ```c %{ #include "lex.yy.h" %} %option noyywrap %{ int yylex(); void yyerror(char *); %} %union { int num; float fnum; char *id; } %token IF ELSE FOR WHILE DO BREAK CONTINUE RETURN %token INT FLOAT %token ADD SUB MUL DIV MOD %token ASSIGN GT GE LT LE NE EQ %token SEMICOLON COMMA %token LPAREN RPAREN LBRACE RBRACE %token IDENTIFIER %% {if} {printf("IF\n");} {else} {printf("ELSE\n");} {for} {printf("FOR\n");} {while} {printf("WHILE\n");} {do} {printf("DO\n");} {break} {printf("BREAK\n");} {continue} {printf("CONTINUE\n");} {return} {printf("RETURN\n");} [0-9]+ {yylval.num = atoi(yytext); printf("INT %d\n", yylval.num);} [0-9]+"."[0-9]+ {yylval.fnum = atof(yytext); printf("FLOAT %f\n", yylval.fnum);} "+" {printf("ADD\n");} "-" {printf("SUB\n");} "*" {printf("MUL\n");} "/" {printf("DIV\n");} "%" {printf("MOD\n");} "=" {printf("ASSIGN\n");} ">" {printf("GT\n");} ">=" {printf("GE\n");} "<" {printf("LT\n");} "<=" {printf("LE\n");} "!=" {printf("NE\n");} "==" {printf("EQ\n");} ";" {printf("SEMICOLON\n");} "," {printf("COMMA\n");} "(" {printf("LPAREN\n");} ")" {printf("RPAREN\n");} "{" {printf("LBRACE\n");} "}" {printf("RBRACE\n");} [a-zA-Z][a-zA-Z0-9]* {yylval.id = strdup(yytext); printf("IDENTIFIER %s\n", yylval.id);} [ \t\n]+ { /* skip whitespace */ } %% int main(int argc, char *argv[]) { FILE *yyin = fopen(argv[1], "r"); if (!yyin) { printf("Cannot open input file!\n"); return -1; } yylex(); fclose(yyin); return 0; } void yyerror(char *s) { printf("%s\n", s); } ``` 4.使用Flex工具生成词法分析器。 可以使用以下命令生成词法分析器: ``` flex lexer.l ``` 该命令将生成一个名为lex.yy.c的文件,即词法分析器。 5.编译并运行测试程序。 可以使用以下命令编译测试程序: ``` gcc -o lexer lex.yy.c -lfl ``` 该命令将生成一个名为lexer的可执行文件。 可以使用以下命令运行测试程序: ``` ./lexer test.c ``` 其中,test.c是一个分析的C程序实验结果: 假设我们有一个名为test.c的C程序,内容如下: ```c #include <stdio.h> int main() { int a = 10; float b = 3.14; if (a > 5) { printf("a is greater than 5\n"); } else { printf("a is less than or equal to 5\n"); } return 0; } ``` 使用词法分析器对该程序进行分析,输出如下: ``` #include <stdio.h> IDENTIFIER printf LPAREN STRING "a is greater than 5\n" RPAREN SEMICOLON INT IDENTIFIER main LPAREN RPAREN LBRACE INT IDENTIFIER a ASSIGN INT 10 SEMICOLON FLOAT IDENTIFIER b ASSIGN FLOAT 3.140000 SEMICOLON IF LPAREN IDENTIFIER a GT INT 5 RPAREN LBRACE IDENTIFIER printf LPAREN STRING "a is greater than 5\n" RPAREN SEMICOLON RBRACE ELSE LBRACE IDENTIFIER printf LPAREN STRING "a is less than or equal to 5\n" RPAREN SEMICOLON RBRACE RETURN INT 0 SEMICOLON RBRACE ``` 可以看到,词法分析器成功地识别出了关键字、标识符整数、浮点数、运算符和界符等,并正确地输出了结果。 实验总结: 本实验中,我们学习了词法分析程序的基本原理和算法,并使用Flex工具和正则表达式编写了一个简单的词法分析器词法分析器能够识别出关键字、标识符整数、浮点数、运算符和界符等,并对输入的代码进行了正确的分析。通过本实验的学习,我们深入理解了编译原理中的词法分析过程,提高了对编译原理的理解和应用能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值