编译原理实验 简单词法分析程序的设计

一、实验目的

了解词法分析程序的基本构造原理,掌握简单词法分析程序的构造方法。

二、实验内容

根据PASCAL语言的说明语句结构,设计一个对PASCAL语言常量说明语句进行词法分析的简单程序,并用C、C++或Java语言编程实现。要求程序能够对从键盘输入或从文件读入的形如 “const count=10,sum=81.5,char1=’f’,string1=”hj”, max=169;”的字符串进行分析处理,判断该输入串是否是一个有效的PASCAL语言常量说明语句。如果不是,则报错;如果是,则识别出该输入串中所说明的各种常量名、常量类型及常量值,并统计各种类型的常量个数。

三、实验要求

1、输入的常量说明串,要求最后以分号作结束标志;

2、根据输入串或读入的文本文件中第一个单词是否为“const”判断输入串或文本文件是否为常量说明内容;

3、识别输入串或打开的文本文件中的常量名。常量名必须是标识符,定义为字母开头,后跟若干个字母,数字或下划线;

4、根据各常量名紧跟等号“=”后面的内容判断常量的类型。其中:字符型常量定义为放在单引号内的一个字符;字符串常量定义为放在双引号内所有内容;整型常量定义为带或不带+、- 号,不以0开头的若干数字的组合;实型常量定义为带或不带+、- 号,不以0开头的若干数字加上小数点再后跟若干数字的组合;

5、统计并输出串或文件中包含的各种类型的常量个数;

6、以二元组(类型,值)的形式输出各常量的类型和值;

7、根据常量说明串置于高级语言源程序中时可能出现的错误情况,模仿高级语言编译器对不同错误情况做出相应处理。

四、运行结果示例

1、输入如下正确的常量说明串:

const count=10,sum=81.5,char1='f',max=169,str1="h*54 2..4S!AAsj", char2='@',str2="aa!+h";

输出:

count(integer,10)”

sum(float,81.5)

char1(char, ‘f’)

max(integer,169)

str1(string,“h*54  2..4S!AAsj”)

char2(char, ‘@’)

str2(string,“aa!+h”)

 

int_num=2;  char_num=2; string_num=2; float_num=1.

2、输入类似如下的保留字const错误的常量说明串:

Aconstt count=10,sum=81.5,char1=‘f’;

输出类似下面的错误提示信息:

It is not a constant declaration statement!

Please input a string again!

3、输入类似如下含常量名或常量值错误的常量说明串:

const count=10,12sum=81.5,char1=‘ff’,max=0016;

输出类似下面的错误提示信息:

count(integer,10)

12sum(Wrong! It is not a identifier!)

char1(Wrong! There are  more than one char in ‘’.)

max(Wrong! The integer can’t be started with ‘0’.)

int_num=1;  char_num=0; string_num=0; float_num=0.

package asds;

import java.util.Scanner;

public class Main {
	static String name; // 存放常量名
	static String value;// 存放常量值
	static String type; // 存放常量值类型
	static String errorInfo;// 存放错误信息
	static int correctName;// 0表示常量名错误,1表示常量名正确
	static int correctValue;// 0表示常量值错误,1表示常量值正确
	static int int_num = 0;
	static int string_num = 0;
	static int float_num = 0;
	static int char_num = 0;// 用于统计各种类型的常量数量
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		String s = in.nextLine();
		s = s.trim();// 去除首尾空格
		boolean result = s.startsWith("const") && s.endsWith(";");
		while (!result) {
			// 如果输入字符串不是以“const"开头并且以”;”结尾,则输出错误信息,并且要求重新输入
			System.out.println("It is not a constant declaration statement! ");
			System.out.println("Please input a string again!");
			s = in.nextLine();
			s = s.trim();
			result = s.startsWith("const") && s.endsWith(";");
		}
		Output(s);
		in.close();
	}
	// 判断常量名是否合法
	public static int checkName(char[] a, int i) {
		name = "";
		while (a[i] != '=') {
			name += a[i];
			i++;
		}
		name = name.trim();
		String regex = "[a-zA-Z_][a-zA-Z0-9_]*";
		boolean result = name.matches(regex);
		if (result) {
			correctName = 1;
		} else {
			correctName = 0;
		}
		return i;
	}

	// 判断常量值的合法性与常量类型
	public static int checkType(char a[], int i) {
		value = "";
		errorInfo = "";
		while (a[i] != ',' && a[i] != ';') {
			value += a[i];
			i++;
		}
		value = value.trim();
		if (correctName == 1) {
			// 判断该数是否为整数
			if (value.matches("[+|-]?[0-9]*")) {
				String s1 = value;
				// 判断符号
				if (value.charAt(0) == '+' || value.charAt(0) == '-') {
					s1 = value.substring(1);
				}
				if (s1.equals("0") || s1.matches("[1-9][0-9]*")) {
					correctValue = 1;
					type = "integer";
					int_num++;
				} else {
					errorInfo = "Wrong! The integer can’t be started with ‘0’.";
					correctValue = 0;
				}
			}
			// 判断该数是否为浮点数
			else if (value.matches("[+|-]?[0-9]*[.][0-9]+")) {
				correctValue = 1;
				type = "float";
				float_num++;
			}

			// 判断常量值是char型
			else if (value.startsWith("'") && value.endsWith("'")) {
				if (value.length() == 3) {
					correctValue = 1;
					type = "char";
					char_num++;
				} else {
					errorInfo += "Wrong! There are  more than one char in ‘’.";
					correctValue = 0;
				}
			}

			// 判断常量名是String型
			else if (value.startsWith("\"") && value.endsWith("\"")) {
				correctValue = 1;
				type = "string";
				string_num++;
			}

			// 其他错误情况
			else {
				correctValue = 0;
				errorInfo += "Wrong! The format of the value string is not correct !";
			}
		}
		return i;
	}
	static void Output(String s) {
		char[] str = s.toCharArray();
		int i = 5;
		while (i < str.length - 1) {
			i = checkName(str, i);
			i = checkType(str, i + 1) + 1;
			// 常量名定义正确,继续判断常量值
			if (correctName == 1) {
				// 常量值正确,输出结果,包含常量名,常量类型以及常量值
				if (correctValue == 1) {
					System.out.println(name + "(" + type + "," + value + ")");
				}
				// 常量值错误,给出错误类型
				else {
					System.out.println(name + "(" + errorInfo + ")");
				}
			}
			// 常量名定义错误
			else {
				System.out.println(name + "("
						+ "Wrong! It is not a identifier!" + ")");
			}
		}
		System.out.println("int_num=" + int_num + ";  char_num=" + char_num
				+ ";  string_num=" + string_num + ";  float_num=" + float_num
				+ ".");
	}

}

 

你可能感兴趣的:(编译原理实验 简单词法分析程序的设计)