编译原理:实验一、无符号数的词法分析程序

内容:掌握词法分析的基本思想,并用高级语言编写无符号数的词法分析程                 序。
要求:从键盘上输入一串字符(包括字母、数字等),最后以 结束,编写
           程序识别出其中的无符号数。
           无符号数文法规则可定义如下:
           < 无符号数 >→< 无符号实数 >│< 无符号整数 >
           < 无符号实数 >→< 无符号整数 >.< 数字串 >[E< 比例因子 >]│
           < 无符号整数 >E< 比例因子 >
           < 比例因子 >→< 有符号整数 >
           < 有符号整数 >→[+│-]< 无符号整数 >
           < 无符号整数 >→< 数字串 >
           < 数字串 >→< 数字 >{< 数字 >}
           < 数字 >→0 1 2 3...... 9
读无符号数的程序流程图见下图
代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;


public class 无符号数的词法分析程序 {
	public static void main(String[] args) throws IOException {
		fun();
		
	}
	
	public static void fun() throws IOException{
		System.out.print("输入符号串:(最后以\";\"结束):");
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String strings = br.readLine();
		
		if (strings.length() == 0 || strings == null) {
			System.out.println("error!");
			return;
		} else {
			int w = 0; // 尾数累加器
			int p = 0; // 指数累加器
			int j = 0; // 十进制小数位数计数器
			int e = 1; // 记录十进制数的符号
			String CJ1; //记录类型
			float Cj2;
			for (int i = 0; i < strings.length(); i++) {
				char ch = strings.charAt(i);
				int d;
				if (i == 0) {
					if (ch > 48 && ch < 58) { //数字  1-9
						d = ch - 48; //数值 => d
						w = w * 10 + d; //w*10+d=>w
					} else { 
						System.out.println("error!");
						return;
					}
				} else {
					if (ch > 47 && ch < 58) { //数字  0-9
						d = ch - 48; //数值 => d
						w = w * 10 + d; //w*10+d=>w
					} else { 
						if (ch == '.') {  //是否是小数点
							i++;
							ch = strings.charAt(i); //取下一个字符
							if (ch < 48 || ch > 58){ //不是数字
								System.out.println("error!");
								return;
							} else { //数字 0-9
								do{
									d = ch - 48; //数值 => d
									w = w * 10 + d; //w*10+d=>w
									j += 1; //j+1=>j
									i++;
									ch = strings.charAt(i); //取下一个字符 
								} while (ch > 47 && ch < 58);
								if (ch == 'E') { //是'E'否
									i++;
									ch = strings.charAt(i); //取下一个字符 
									if (ch == '-') { //是'-'否
										e = -1;
										i++;
										ch = strings.charAt(i); //取下一个字符 
									}else if (ch == '+') { //是'+'否
										i++;
										ch = strings.charAt(i); //取下一个字符 
									}
									
									if (ch < 48 || ch > 58){ //不是数字
										System.out.println("error!");
										return;
									} else {
										do{
											d = ch - 48; //数值 => d
											p = p * 10 + d; //p*10+d=>p
											i++;
											ch = strings.charAt(i); //取下一个字符 
										} while (ch > 47 && ch < 58);
										
										CJ1 = "实型";
										Cj2 = (float) (w * Math.pow(10.0, e * p - j));
										System.out.println(CJ1 +"_"+Cj2);
										return;
									}
								} else {
									CJ1 = "实型";
									Cj2 = (float) (w * Math.pow(10.0, e * p - j));
									System.out.println(CJ1 +"_"+Cj2);
									return;
								}
							}
	
						} else {
							if (ch == 'E') {  //是否是E
								i++;
								ch = strings.charAt(i); //取下一个字符 
								if (ch == '-') { //是'-'否
									e = -1;
									i++;
									ch = strings.charAt(i); //取下一个字符 
								}else if (ch == '+') { //是'+'否
									i++;
									ch = strings.charAt(i); //取下一个字符 
								}
								
								if (ch < 48 || ch > 58){ //不是数字
									System.out.println("error!");
									return;
								} else {
									do{
										d = ch - 48; //数值 => d
										p = p * 10 + d; //p*10+d=>p
										i++;
										ch = strings.charAt(i); //取下一个字符 
									} while (ch > 47 && ch < 58);
									
									CJ1 = "实型";
									Cj2 = (float) (w * Math.pow(10.0, e * p - j));
									System.out.println(CJ1 +"_"+Cj2);
									return;
								}
							} else {
								CJ1 = "整型";
								Cj2 = (float) (w * Math.pow(10.0, e * p - j));
								System.out.println(CJ1 +"_"+Cj2);
							}
						}
					}
				}
				
			}
		}
	}
}

实验结果:

  • 10
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include<iostream> #include<cctype> #include<cstring> #include<cmath> using namespace std; int w=0; //尾累加器 int p=0; //指累加器 int j=0; //十进制小器 int e=1; //用来记录十进制的符号,当指为正时为1,为负时为-1 int i=0; //用来标志元素位置 int d=0; //用来表示每个值型元素对应的值 const int N=40;//用来确定输入识别符的最大长度 char data[N];//存放输入的识别符 bool is_digit; //标志是否是字 string CJ1;//确定是整形还是实型 double CJ2;//记值 //函声明 void check(char c);//检查首字母是否是字的函 void deal_integer(char c);//处理识别符的整部分 void deal_point(char c);//用来处理小部分 void deal_index(char c);//用来处理指部分 void s_next();// 确定实型 void z_next();//确定整型 void last();// 计算 CJ2 void error();//程序中错误处理程序 void deal();//处理函主体 int main(){ //主函 cout<<"please input your data,and its maximum length is "<<N<<":"<<endl;//等待用户输入识别符 cin>>data; deal();//处理函主体 last();// 计算 CJ2 system("pause"); return 0; } void check(char c) //判断输入的首字母是否是字 { is_digit=isdigit(c); while(is_digit!=true){//输入的首字母不是字时 cout<<"\nError! Try again.."<<endl;//要求重新输入 cin>>data; check(data[0]); } } void deal_integer(char c){//处理识别符的整部分 d=(int)c-48; w=w*10+d; i++; if(isdigit(data[i])!=0)//下一个仍是值时,调用程序本身 deal_integer(data[i]); } void deal_point(char c){//用来处理小部分 int temp=i; if(isdigit(c)!=0)//是值字符时 deal_integer(c); else { error(); //错误处理程序 deal();//处理函主体 } j=i-temp;//记录十进制小 } void deal_index(char c){//用来处理指部分 if(c=='-') {e=-1;i++;}//是'-'号时 else {if(c=='+') i++;//是'+' 号时 else { if(isdigit(c)==false) //非值字符时 { error();//错误处理程序 deal();//处理函主体 } else { d=(int)c-48;//把输入字符转换为整型 goto pro2;} } } if(isdigit(data[i])!=0) pro1: d=(int)(data[i])-48; pro2: p=p*10+d; i++; if(isdigit(data[i])!=0)//是值字符时 goto pro1; else if(data[i]!='\0'){//非结束标志 error();//错误处理程序 deal();//处理函主体 } else s_next(); // 确定实型 } void s_next(){// 确定实型 i--;//退一个字符 CJ1="实型"; } void z_next(){//确定整型 i--;//退一个字符 CJ1="整型"; } void last(){// 计算 CJ2 CJ2=w*pow((double)10,e*p-j); cout<<CJ1<<": "<<CJ2<<endl;//输出 } void error(){//程序中错误处理程序 cout<<"\nError! Try again.."<<endl;//重新输入据 cin>>data; p=0;w=0;j=0; //所有全局变量重新初始化 e=1;i=0;d=0; //exit(0); } void deal(){ check(data[0]);//判断输入的首字母是否是字 deal_integer(data[i]);//处理识别符的整部分 if(data[i]=='.') { deal_point(data[++i]);//用来处理小部分 if(data[i]=='e'||data[i]=='E')//如果是e或E时 deal_index(data[++i]);//用来处理指部分 else if(data[i]!='\0') { error();//错误处理程序 deal();//处理函主体 } else s_next();// 确定实型 } else { if(data[i]=='e'||data[i]=='E')//如果是e或E时 { deal_index(data[++i]);//用来处理指部分 //CJ1="整型"; } else if(data[i]!='\0'){ //非结束标志 error();//错误处理程序 deal();//处理函主体 } else z_next();//确定整型 } }
实验目的: 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、付费专栏及课程。

余额充值