一个简单词法分析器的实现代码(java实现)

来源:互联网 发布:手机噪声测试软件 编辑:程序博客网 时间:2024/05/22 03:30

http://www.cnblogs.com/xuqiang/archive/2010/09/21/1953501.html

Main.java

Lexer.java

Num.java

Tag.java

Token.java

Word.java

Type.java

 

============

http://freewxy.iteye.com/blog/870016

什么是词法? 

 

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

 

什么是词法分析?

 

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

 

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

 

 1) 关键字

  begin if then while do end

 2) 运算符和界符

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

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

  ID=letter(letter|digit)*

  NUM=digitdigit*

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

 

 

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

单词符号

种别码

单词符号

种别码

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, tokensum)构成的序列。

  syn为单词种别码;

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

  sum为整形常数。

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

 

 

 

程图:


 源码:

 

Java代码 复制代码 收藏代码
  1. public class 词法分析 {   
  2.      
  3.     /*  初始化数据  
  4.       syn为单词种别码;  
  5.       token为存放的单词自身字符串;  
  6.       sum为整型常数。  
  7.      */  
  8.     static String prog;   
  9.     static char ch;   
  10.     static char[]token=new char[8];   
  11.     static int syn,p,m,n,sum;   
  12.     static //关键字表的初值  
  13.     String[] rwtable={"begin","if","then","while","do","end"};   
  14.        
  15.     /**  
  16.      * @param args  
  17.      * @throws IOException   
  18.      */  
  19.     public static void main(String[] args) throws IOException {   
  20.          //1、输入字符串   
  21.          //prog="begin  x:=9; if x>0  then   x:=2*x+1/3;end #";  
  22.          //1、从文件中读取字符串   
  23.         prog=dofile.readFileByChars("src/data.txt");   
  24.          //2、扫描输出   
  25.          p=0;   
  26.          do{   
  27.              scaner();   
  28.              switch(syn){   
  29.              case 11:System.out.print("("+syn+" , ");//单词符号:Digit digit*  
  30.                      System.out.print(sum);   
  31.                      System.out.println(")");   
  32.                 break;   
  33.              case -1:System.out.println("error!");   
  34.                 break;   
  35.              default:   
  36.                      System.out.print("(");   
  37.                      System.out.print(syn);    
  38.                      System.out.print(" , ");   
  39.                      String str=new String(token);   
  40.                      System.out.print(str);   
  41.                      System.out.println(")");   
  42.              }   
  43.          }while(syn!=0);   
  44.             
  45.             
  46.     }   
  47.     //扫描程序   
  48.     private static void scaner() throws IOException {          
  49. //      1、初始化   
  50.         for(int i=0;i<8;i++)   
  51.             token[i]=' ';   
  52. //      2、读字母   
  53.         ch=prog.charAt(p++);   
  54.         while(ch==' '){//如果是空格,则取下一个字符  
  55.             ch=prog.charAt(p++);   
  56.         }   
  57. //      3、开始执行扫描   
  58. //          1、是字母   
  59. //                     读标识符,查保留字表   
  60. //                         查到,换成属性字表,写到输出流  
  61. //                         没查到, 查名表,换成属性字,写到输出流  
  62.         if(ch>='a'&&ch<='z'){   
  63.             m=0;   
  64.             //获取完整单词   
  65.             while((ch>='a'&&ch<='z')||(ch>='0'&&ch<='9')){   
  66.                 token[m++]=ch;   
  67.                 ch=prog.charAt(p++);   
  68.             }   
  69.             token[m++]='\0';   
  70.             --p;   
  71.             syn=10;//单词符号为letter(letter|digit)*  
  72.             //判断是哪个关键字   
  73.             String newStr=new String(token);   
  74.             newStr=newStr.trim();   
  75.             //System.out.println("newStr:"+newStr);  
  76.             for(n=0;n<6;n++){   
  77.                 //System.out.println("rwtable:"+rwtable[n]);  
  78.                 if(newStr.equals(rwtable[n])){   
  79.                     syn=n+1;   
  80.                     System.out.println("syn 的值是:"+syn);   
  81.                     break;   
  82.                 }   
  83.             }   
  84.             token[m++]='\0';   
  85.         }   
  86. //          2、是数字   
  87. //                         取数字,查常量表,换成属性字表,写到输出流  
  88.         else if(ch>='0'&&ch<='9'){   
  89.             while(ch>='0'&&ch<='9'){   
  90.                 sum=sum*10+ch-'0';   
  91.                 ch=prog.charAt(p++);   
  92.             }   
  93.             --p;   
  94.             syn=11;//digitdigit*  
  95.             token[m++]='\0';   
  96.         }   
  97. //          3、是特殊符号   
  98. //                         查特殊符号表,换成属性字。写到输出流  
  99. //          4、错误error   
  100. //      4、是否分析结束   
  101. //              未结束,到2   
  102. //              结束,到出口   
  103.         else    
  104.         switch(ch){   
  105.             case'<':   
  106.                 m=0;   
  107.                 token[m++]=ch;   
  108.                 ch=prog.charAt(p++);   
  109.                 if(ch=='>'){   
  110.                     syn=21;//<>  
  111.                 }   
  112.                 else if(ch=='='){   
  113.                     syn=22;//<=  
  114.                     token[m++]=ch;   
  115.                 }   
  116.                 else{   
  117.                     syn=20;//<  
  118.                     --p;   
  119.                 }   
  120.             break;   
  121.             case'>':   
  122.                 token[m++]=ch;   
  123.                 ch=prog.charAt(p++);   
  124.                 if(ch=='='){   
  125.                     syn=24;//>=  
  126.                 }   
  127.                 else{   
  128.                     syn=23;//>  
  129.                     --p;   
  130.                 }   
  131.                 break;   
  132.             case':':   
  133.                 token[m++]=ch;   
  134.                 ch=prog.charAt(p++);   
  135.                 if(ch=='='){   
  136.                     syn=18;//:=  
  137.                     token[m++]=ch;   
  138.                 }   
  139.                 else{   
  140.                     syn=17;//:  
  141.                     --p;   
  142.                 }   
  143.             break;   
  144.             case'+':   
  145.                 syn=13;token[0]=ch;token[1]='\0';break;   
  146.             case'-':   
  147.                 syn=14;token[0]=ch;token[1]='\0';break;   
  148.             case'*':   
  149.                 syn=15;token[0]=ch;token[1]='\0';break;   
  150.             case'/':   
  151.                 syn=16;token[0]=ch;token[1]='\0';break;   
  152.             case'=':   
  153.                 syn=25;token[0]=ch;token[1]='\0';break;   
  154.             case';':   
  155.                 syn=26;token[0]=ch;token[1]='\0';break;   
  156.             case'(':   
  157.                 syn=27;token[0]=ch;token[1]='\0';break;   
  158.             case')':   
  159.                 syn=28;token[0]=ch;token[1]='\0';break;   
  160.             case'#':   
  161.                 syn=0;token[0]=ch;token[1]='\0';break;   
  162.             default:   
  163.                 syn=-1;    
  164.                    
  165.         }   
  166.            
  167.         File txt=new File("src/nihao.txt");   
  168.            if(!txt.exists()){   
  169.                txt.createNewFile();   
  170.            }   
  171.            byte[] bytes=new byte[token.length];//定义一个长度与需要转换的char数组相同的byte数组  
  172.            for(int i=0;i<bytes.length ;i++){//循环将char的每个元素转换并存放在上面定义的byte数组中  
  173.                byte b=(byte)token[i];//将每个char转换成byte  
  174.                bytes[i]=b;//保存到数组中   
  175.            }   
  176.            FileOutputStream fos;   
  177.         try {   
  178.             fos = new FileOutputStream(txt,true);   
  179.             fos.write(syn);   
  180.             fos.write(bytes);   
  181.                
  182.                fos.close();   
  183.         } catch (Exception e) {   
  184.             e.printStackTrace();   
  185.         }     
  186.     }   
  187. }  

 

 

文件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-->