编译原理实验一 -无符号数的词法分析程序


一、实验目的和要求:

1.掌握词法分析的基本思想,并用高级语言编写无符号数的词法分析程序。

2.要求从键盘上输入一串字符(包括字母、数字等),最后以“;”结束,编

写程序识别出其中的无符号数

二、实验平台:

   Java语言

三、主要实验内容及结果:

实验内容:

词法分析的主要任务是:扫描源程序,识别单词,生成属性字。单词的种类一般分为四种:关键字、标识符、常数、特殊符号,无符号数是常数中的一种,无符号数的词法分析难点在于带指数的无符号数的识别。

无符号数文法规则可定义如下:

<无符号数>→<无符号实数>│<无符号整数>

<无符号实数>→<无符号整数>.<数字串>[E<比例因子>]│

<无符号整数>E<比例因子>

<比例因子>→<有符号整数>

<有符号整数>→[+│-]<无符号整数>

<无符号整数>→<数字串>

<数字串>→<数字>{<数字>}

<数字>→0 │1 │2 │3...... │9

             程序代码:

import java.util.ArrayList;
import java.util.Scanner;

public class Unsigned {

    private ArrayList wordList;

    public static void main(String[] args) {

        Unsigned unsigned = new Unsigned();
        // 读入单词列表
       
unsigned.inputWordList();
        // 识别单词列表
       
for (Word word : unsigned.wordList) {
            // 识别单词
           
unsigned.whichType(word);
            String temp = word.getCJ2();
            if (temp != null) {
                int index = temp.lastIndexOf(".0");
                if (index == temp.length() - 2)
                    word.setCJ2(temp.substring(0, index));
            }
        }
        // 输出单词列表
       
unsigned.printWordList();
    }

    // 识别单词
   
private void whichType(Word word) {

        int w = 0;
        int p = 0;
        int j = 0;
        int e = 1;
        int d = 0;
        String chars[] = word.getStr().split("");
        // 从第一个字符开始
       
int i = 0;
        String current_char = chars[i];
        // 数字否?
       
if (!isNum(current_char)) {
            word.setCJ1("出错");
            return;
        } else {
            while (true) {
                d = Integer.parseInt(current_char);
                w = w * 10 + d;
                current_char = chars[++i];
                // 数字否?
               
if (isNum(current_char)) {
                    continue;
                } else {
                    // '.'?
                   
if (current_char.equals(".")) {
                        current_char = chars[++i];
                        // 数字否?
                       
if (!isNum(current_char)) {
                            word.setCJ1("出错");
                            return;
                        } else {
                            while (true) {
                                d = Integer.parseInt(current_char);
                                w = w * 10 + d;
                                j = j + 1;
                                current_char = chars[++i];
                                // 数字否?
                                
if (isNum(current_char)) {
                                    continue;
                                } else {
                                    // 'E'?
                                   
if (current_char.equals("E")) {
                                        isE(current_char, chars, i, word, w, p, j, e, d);
                                        return;
                                    } else {
                                        // 退一字符
                                        
word.setCJ1("实型");
                                        word.setCJ2((w * Math.pow(10, e * p - j)) + "");
                                        return;
                                    }
                                }
                            }
                        }
                    } else {
                        // 'E'?
                       
if (current_char.equals("E")) {
                            isE(current_char, chars, i, word, w, p, j, e, d);
                            return;
                        } else {
                            // 退一字符
                           
word.setCJ1("整型");
                            word.setCJ2((w * Math.pow(10, e * p - j)) + "");
                            return;
                        }
                    }
                }
            }
        }
    }

    private void isE(String current_char, String[] chars, int i, Word word, int w, int p, int j, int e, int d) {

        current_char = chars[++i];
        // '-'?
       
if (current_char.equals("-")) {
            e = -1;
            current_char = chars[++i];
            // 数字否?
           
if (isNum(current_char)) {
                while (true) {
                    d = Integer.parseInt(current_char);
                    p = p * 10 + d;
                    current_char = chars[++i];
                    if (isNum(current_char)) {
                        continue;
                    } else {
                        // 退一字符
                       
word.setCJ1("实型");
                        word.setCJ2((w * Math.pow(10, e * p - j)) + "");
                        return;
                    }
                }
            } else {
                word.setCJ1("出错");
                return;
            }
        } else {
            // '+'?
           
if (current_char.equals("+")) {
                current_char = chars[++i];
                // 数字否?
               
if (isNum(current_char)) {
                    while (true) {
                        d = Integer.parseInt(current_char);
                        p = p * 10 + d;
                        current_char = chars[++i];
                        if (isNum(current_char)) {
                            continue;
                        } else {
                            // 退一字符
                           
word.setCJ1("实型");
                            word.setCJ2((w * Math.pow(10, e * p - j)) + "");
                            return;
                        }
                    }
                } else {
                    word.setCJ1("出错");
                    return;
                }
            } else {
                // 数字否?
               
if (isNum(current_char)) {
                    while (true) {
                        d = Integer.parseInt(current_char);
                        p = p * 10 + d;
                        current_char = chars[++i];
                        if (isNum(current_char)) {
                            continue;
                        } else {
                            // 退一字符
                           
word.setCJ1("实型");
                            word.setCJ2((w * Math.pow(10, e * p - j)) + "");
                            return;
                        }
                    }
                } else {
                    word.setCJ1("出错");
                    return;
                }
            }
        }
    }

    // 是否为数字
   
private boolean isNum(String string) {

        return "0123456789".contains(string);
    }

    // 读入单词列表
   
private void inputWordList() {

        System.out.println("12996 0269 0E Es265 ;要求从键盘上输入一串字符(包括字母、数字等),最后以“;”结束");
        Scanner scanner = new Scanner(System.in);
        String temp = scanner.nextLine().replace(";", "");
        scanner.close();
        String[] strs = temp.split(" ");
        wordList = new ArrayList();
        for (String str : strs) {
            Word word = new Word();
            word.setStr(str + "#");
            wordList.add(word);
        }
    }

    // 输出单词列表
   
private void printWordList() {

        for (Word word : wordList) {
            System.out.println(word.getStr() + "\t" + word.getCJ2() + "\t" + word.getCJ1());
        }
    }

    // 单词类
   
private class Word {
        // str记原始单词
       
private String str;
        // CJ1记类型
       
private String CJ1;
        // CJ1记数值
       
private String CJ2;

        public String getStr() {
            return str;
        }

        public void setStr(String str) {
            this.str = str;
        }

        public String getCJ1() {
            return CJ1;
        }

        public void setCJ1(String cJ1) {
            CJ1 = cJ1;
        }

        public String getCJ2() {
            return CJ2;
        }

        public void setCJ2(String cJ2) {
            CJ2 = cJ2;
        }
    }
}

运行结果:

          

四、心得体会

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