第五次作业--词法分析程序的设计与实现(20191010)

词法分析程序(Lexical Analyzer)要求:

- 从左至右扫描构成源程序的字符流

-  识别出有词法意义的单词(Lexemes

-  返回单词记录(单词类别,单词本身)

-  滤掉空格

-  跳过注释

-  发现词法错误

程序结构:

输入:字符流(什么输入方式,什么数据结构保存)

处理:

–遍历(什么遍历方式)

–词法规则

输出:单词流(什么输出形式)

–二元组

单词类别:

1.标识符(10)

2.无符号数(11)

3.保留字(一词一码)

4.运算符(一词一码)

5.界符(一词一码)

单词符号

种别码

单词符号

种别码

begin

1

:

17

if

2

:=

18

then

3

<

20

while

4

<=

21

do

5

<>

22

end

6

>

23

l(l|d)*

10

>=

24

dd*

11

=

25

+

13

;

26

-

14

(

27

*

15

)

28

/

16

#

0

因为自己对运用Java语言编写程序比较熟悉,所以用Java编写了这次的词法分析程序。将字符与种别码分别对应起来,区分数字分隔符。

程序代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

public class LexicalAnalyzer {

    static String[] keyWords=new String[]{"main","if","then","while","do","static",
                                "int","double","struct","break","else",
                                "long","switch","case","typedef","char",
                                "return","const","float","short","continue",
                                "for","void","sizeof"};   //关键字种别码从1开始
    static char ch;
    static int index;
    static int syn, sum=0, row;
    static String str="";   
    static StringBuilder word=new StringBuilder("");    //建立StringBuilder,方便读取文字信息追加
    public static void main(String[] args) {
    	 index=0;
    	 row=1;//从第一行开始扫描
   	 System.out.println("请输入一段C语言源程序字符串(以#符号结束):");
       BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
       try{
           do{
           	String testStr;
           	testStr=bf.readLine();
               str+=testStr;
               ch=testStr.charAt(testStr.length()-1); //读到单词最后一个字符
           }while(ch!='#');        
       }catch(IOException e){
           e.printStackTrace();
       }
       index=0; //重置单词字符索引
       do{
    	   Analyzer();
    	   //输出数字及种别码
           if (syn==26) {
           	System.out.println("("+syn+","+sum+")");
			}
           else if (syn==-1) {
           	System.out.println("没有该符号的种别码!!!");
			}
           else if (syn==-2) {
			}
           else {
           	System.out.println("("+syn+","+word+")");
			}
       }while(syn!=0);
   }

    static void Analyzer(){
    	//将单词容器清空
    	word.delete(0, word.length());          
        ch=str.charAt(index++);//获取单词每一个字符
        //跳过空格
        while(ch==' '){
            ch=str.charAt(index++);      
        }
        if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){         //判断是关键字还是标识符
            while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){
            	word.append(ch);
                ch=str.charAt(index++);
            }
            index--;      //回退标记
            syn=25;      
            String s=word.toString();
            //判断为关键字
            for(int i=0; i<keyWords.length; i++){
                if(s.equals(keyWords[i])){     
                    syn=i+1;
                    break;        
                }
            }
        }
        //判断为是数字
        else if((ch>='0'&&ch<='9')){
            sum=0;
            while((ch>='0'&&ch<='9')){
                sum=sum*10+ch-'0';
                ch=str.charAt(index++);
            }
            index--;
            syn=26;
        }
        //判断为各种字符
        else switch(ch){

        case '<':
            word.append(ch);
            ch=str.charAt(index++);
            //判断是否是<=
            if(ch=='='){
                word.append(ch);
                syn=35;
            }
            //判断是否是<>
            else if(ch=='>'){
                word.append(ch);
                syn=34;
            }
            //判断为<
            else{
                syn=33;
                index--;
            }
            break;
        case '>':
        	word.append(ch);
            ch=str.charAt(index++);
          //判断是否是>=
            if(ch=='='){
            	word.append(ch);
                syn=37;
            }
          //判断是>
            else{
                syn=36;
                index--;
            }
            break;
        case '*':
        	word.append(ch);
            ch=str.charAt(index++);
          //判断是否是**
            if(ch=='*'){
            	word.append(ch);
                syn=31;
            }
          //判断是*
            else{
                syn=13;
                index--;
            }
            break;
        case '=':
        	word.append(ch);
            ch=str.charAt(index++);
          //判断是否是==
            if(ch=='='){
                syn=32;
                word.append(ch);
            }
          //判断是=
            else{
                syn=38;
                index--;
            }
            break;
        case '/':
        	word.append(ch);
            ch=str.charAt(index++);
          //判断是否是注释
            if(ch=='/'){
                while(ch!=' '){
                    ch=str.charAt(index++);   //判断里面是否有空格
                }
                syn=-2;
                break;
            }
          //判断是/
            else{
                syn=30;
                index--;
            }
            break;
          //判断是+
        case '+':
            syn=27;
            word.append(ch);
            break;
          //判断是-
        case '-':
            syn=28;
            word.append(ch);
            break;
          //判断是;
        case ';':
            syn=41;
            word.append(ch);
            break;
          //判断是(
        case '(':
            syn=42;
            word.append(ch);
            break;
          //判断是)
        case ')':
            syn=43;
            word.append(ch);
            break;
          //判断是#
        case '#':
            syn=0;
            word.append(ch);
            break;
          //判断是回车
        case '\n':
            syn=-2;
            word.append(ch);
            break;
            //没有种别码
        default:
            syn=-1;
        }
    }
    }
   

  运行结果:

猜你喜欢

转载自www.cnblogs.com/codekid/p/11655717.html
今日推荐