读书人

java兑现简单的词法分析仿真

发布时间: 2012-12-28 10:29:04 作者: rapoo

java实现简单的词法分析仿真

?

什么是词法??

?

??所谓词法,源代码由字符流组成,字符流中包括关键字,变量名,方法名,括号等等符号,其中变量名要满足不能包括标点符号,不能以数字开头的数字与字母的字符串这个条件,对于括号要成对出现等等,这就是词法;

?

什么是词法分析?

?

??词法分析阶段是编译过程的第一个阶段。这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。

?

待分析的简单语言的词法:

?

?1)?关键字

??begin?if?then?while?do?end

?2)?运算符和界符

??:=?+?-?*?/?<?<=?>?>=?<>?=?;?(?)?#

?3)?其他单词是标识符(ID)和整形常数(NUM),通过以下正规式定义:

??ID=letter(letter|digit)*

??NUM=digitdigit*

?4)?空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM、运算符、界符和关键字,词法分析阶段通常被忽略。

?

?

??????????????????????? 各种单词符号对应的种别编码

单词符号

种别码

单词符号

种别码

begin

1

:

17

if

2

:=

18

then

3

<

20

while

4

<>

21

do

5

<=

22

end

6

>

23

letter(letter|digit)*

10

>=

24

digitdigit*

11

=

25

+

13

;

26

-

14

(

27

*

15

)

28

/

16

#

0

?

?

词法分析程序的功能:

?

??输入:所给文法的源程序字符串

??输出:二元组(syn,?token或sum)构成的序列。

??syn为单词种别码;

??token为存放的单词自身字符串;

??sum为整形常数。

??例如:对源程序begin?x:=9;if?x>0?then?x:=2*x+1/3;end#?经词法分析后输出如下序列:(1,begin)(10,’x’)?(18,:=)?(11,9)?(26,;)?(2,if)……

?

?

?

流程图:


java兑现简单的词法分析仿真

?源码:

?

public class 词法分析 {  /*  初始化数据  syn为单词种别码;  token为存放的单词自身字符串;  sum为整型常数。 */static String prog;static char ch;static char[]token=new char[8];static int syn,p,m,n,sum;static //关键字表的初值String[] rwtable={"begin","if","then","while","do","end"};/** * @param args * @throws IOException  */public static void main(String[] args) throws IOException {     //1、输入字符串 //prog="begin  x:=9; if x>0  then   x:=2*x+1/3;end #"; //1、从文件中读取字符串prog=dofile.readFileByChars("src/data.txt"); //2、扫描输出 p=0; do{ scaner(); switch(syn){ case 11:System.out.print("("+syn+" , ");//单词符号:Digit digit*         System.out.print(sum);         System.out.println(")");    break; case -1:System.out.println("error!");    break; default:     System.out.print("(");         System.out.print(syn);          System.out.print(" , ");         String str=new String(token);         System.out.print(str);                 System.out.println(")"); } }while(syn!=0);  }    //扫描程序private static void scaner() throws IOException {//1、初始化for(int i=0;i<8;i++)token[i]=' ';//2、读字母ch=prog.charAt(p++);while(ch==' '){//如果是空格,则取下一个字符ch=prog.charAt(p++);}//3、开始执行扫描//    1、是字母//               读标识符,查保留字表//                   查到,换成属性字表,写到输出流//                   没查到, 查名表,换成属性字,写到输出流if(ch>='a'&&ch<='z'){m=0;//获取完整单词while((ch>='a'&&ch<='z')||(ch>='0'&&ch<='9')){token[m++]=ch;ch=prog.charAt(p++);}token[m++]='\0';--p;syn=10;//单词符号为letter(letter|digit)*//判断是哪个关键字String newStr=new String(token);newStr=newStr.trim();//System.out.println("newStr:"+newStr);for(n=0;n<6;n++){//System.out.println("rwtable:"+rwtable[n]);if(newStr.equals(rwtable[n])){syn=n+1;System.out.println("syn 的值是:"+syn);break;}}token[m++]='\0';}//    2、是数字//                   取数字,查常量表,换成属性字表,写到输出流else if(ch>='0'&&ch<='9'){while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=prog.charAt(p++);}--p;syn=11;//digitdigit*token[m++]='\0';}//    3、是特殊符号//                   查特殊符号表,换成属性字。写到输出流//    4、错误error//4、是否分析结束//        未结束,到2//        结束,到出口else switch(ch){case'<':m=0;token[m++]=ch;ch=prog.charAt(p++);if(ch=='>'){syn=21;//<>}else if(ch=='='){syn=22;//<=token[m++]=ch;}else{syn=20;//<--p;}break;case'>':token[m++]=ch;ch=prog.charAt(p++);if(ch=='='){syn=24;//>=}else{syn=23;//>--p;}break;case':':token[m++]=ch;ch=prog.charAt(p++);if(ch=='='){syn=18;//:=token[m++]=ch;}else{syn=17;//:--p;}break;case'+':syn=13;token[0]=ch;token[1]='\0';break;case'-':syn=14;token[0]=ch;token[1]='\0';break;case'*':syn=15;token[0]=ch;token[1]='\0';break;case'/':syn=16;token[0]=ch;token[1]='\0';break;case'=':syn=25;token[0]=ch;token[1]='\0';break;case';':syn=26;token[0]=ch;token[1]='\0';break;case'(':syn=27;token[0]=ch;token[1]='\0';break;case')':syn=28;token[0]=ch;token[1]='\0';break;case'#':syn=0;token[0]=ch;token[1]='\0';break;default:syn=-1;}        File txt=new File("src/nihao.txt");           if(!txt.exists()){           txt.createNewFile();           }           byte[] bytes=new byte[token.length];//定义一个长度与需要转换的char数组相同的byte数组           for(int i=0;i<bytes.length ;i++){//循环将char的每个元素转换并存放在上面定义的byte数组中           byte b=(byte)token[i];//将每个char转换成byte           bytes[i]=b;//保存到数组中           }           FileOutputStream fos;try {fos = new FileOutputStream(txt,true);fos.write(syn);fos.write(bytes);           fos.close();} catch (Exception e) {e.printStackTrace();}  }}

?

?

文件data.txt中的内容为:

? begin? x:=9; if x>0? then?? x:=2*x+1/3;end #

?

程序执行结果(控制台输出):

?

打开文件 src/data.txt 读取内容为:
beginx:=9;ifx>0thenx:=2*x+1/3;end#
syn 的值是:1
(1 , begin)

(10,x)

(18,:=)

(11,9)

(26,;)

syn的值是:2

(2,if)

(10,x)

(23,>)

(11,90)

syn的值是:3

(3,then)

(10,x)

(13,+)

(11,902)

(15,*)

(10,x)

(13,+)

(11,9021)

(16,)

(11,90213)

(26,;)

syn的值是:6

(6,end)

(0,#)

?

<!--EndFragment-->

读书人网 >编程

热点推荐