一、实验目的
了解词法分析程序的基本构造原理,掌握词法分析程序的手工构造方法。
二、实验内容
1
2PASCAL语言的说明语句形式,用手工方法构造一个对说明语句进行词法分析的程序。该程序能对从键盘输入或从文件读入形如:
“const count=10,sum=81.5, char1=’f’, string1=”hj”,max=169;”
的常量说明串进行处理,分析常量说明串中各常量名、常量类型及常量值,并统计各种类型常量个数。
三、实验要求
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)
max(integer,169)
str2(string,“aa!+h”)
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!)
max(Wrong! The integer can’t be started with ‘0’.)
4、其他类型的错误处理情况(略)。
import java.util.Scanner;
public class test01 {
public static void main(String[] args) {
//System.out.println(":123".matches("[+|-]?[0-9]*[.][0-9]+"));
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();
}
Output(s);
in.close();
}
//判断常量名是否合法
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;
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;
}
}
//判断该数是否为浮点数
if(value.length()==3){
correctValue=1;
type="char";
char_num++;
}
else{
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;
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!"+")");
}
}
}
}
本人写代码能力比较挫,如果有样例通不过,或者大家有更好的,欢迎大家提出来