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

一、实验目的

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

二、实验内容

根据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.

4、其他类型的错误处理情况(略)。

五、实验提示

本实验重点有三个:一是作为常量名的标识符的识别;二是如何根据“=”后出现的内容来判断常量类型;三是对各种错误的处理。难点是对整型和实型常量的判断必须综合考虑多种可能情况。

建议:1、用指针或数组与指针相结合来处理输入的常量说明串;2、对整型和实型常量处理时,重点考虑常数中‘0’的位置。

六、分析与讨论

1、若考虑用E或e的科学计数法来表示整数和实数,应该如何实现?

2、若考虑布尔型常量,且规定其值只能为true或false,应该如何实现?

3、如何对手工构造的词法分析程序做进一步的优化,以提高代码质量和运行效率?

分析表

 

FIRST

FOLLOW

S

(,m

#,)

A

(,m

+,#,)

T

+,$

#,)

U

*,$

+,#,)

B

(,m

*,+,#,)

 

SELECT

S->AT

(,m

A->BU

(,m

T->+AT

+

T->$

#,)

U->*BU

*

U->$

+,#,)

B->(S)

(

B->m

M

 

 

m

(

)

+

*

    #

S

->AT

->AT

 

 

 

 

A

->BU

->BU

 

 

 

 

T

 

 

->$

->+AT

 

->$

U

 

 

->$

->$

->BU

->$

B

->m

->(S)

 

 

 

 

个人实验代码(我的判断是依据""来的,如果里面有什么其他符号,请加转义符进行符号插入):

import java.util.*;

public class Main {
	static int int_num=0;
	static int char_num=0; 
	static int string_num=0; 
	static int float_num=0;
	static String name;//变量名
	static String string;//值
	static int namefg = 0;//变量名检验
	static int stringfg = 0;//变量值检验
	static String type;//类型
	static String value;//值
	static int kong = 0;
	//static int flag = 0;
	public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String s = in.nextLine();
        boolean result=s.startsWith("const ");//检查开头
        if(!result){
        	System.out.println("开头校检失败!");
        }else {
			CutString(s);//分隔字符串
			in.close();
		}
	}

	public static void CutString(String s) {//分割校检
		
		// TODO Auto-generated method stub
		char []str = s.toCharArray();//字符串转成字符串数组
		int i = 6;
		while(i

 

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