一、实验目的和要求:

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

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

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

二、实验平台:

   Java语言

 

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

实验内容:

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

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

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

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

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

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

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

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

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

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

             程序代码:

import java.util.ArrayList;

import java.util.Scanner;


public class Unsigned {


    private ArrayList<Word> 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<Word>();

        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;

        }

    }

}

 

运行结果:

 

编译原理语法分析程序java 编译原理词法分析程序java_Word

 

 

          

四、心得体会

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