词法分析

丶灬走出姿态 提交于 2019-12-18 16:40:30
词法分析器
 
定义:
词法分析器的功能输入源程序,按照构词规则分解成一系列单词符号。单词是语言中具有独立意义的最小单位,包括关键字、标识符、运算符、界符和常量等
(1) 关键字 是由程序语言定义的具有固定意义的标识符。例如,Pascal 中的begin,end,if,while都是保留字。这些字通常不用作一般标识符。
(2) 标识符 用来表示各种名字,如变量名,数组名,过程名等等。
(3) 常数  常数的类型一般有整型、实型、布尔型、文字型等。
(4) 运算符 如+、-、*、/等等。
(5) 界符  如逗号、分号、括号、等等。
输出:
词法分析器所输出单词符号常常表示成如下的二元式:
                 (单词种别,单词符号的属性值)
单词种别通常用整数编码。标识符一般统归为一种。常数则宜按类型(整、实、布尔等)分种。关键字可将其全体视为一种。运算符可采用一符一种的方法。界符一般用一符一种的方法。对于每个单词符号,除了给出了种别编码之外,还应给出有关单词符号的属性信息。单词符号的属性是指单词符号的特性或特征。

示例:

比如如下的代码段:

while(i>=j) i--

经词法分析器处理后,它将被转为如下的单词符号序列:
   <while, _>
   <(, _>
   <id, 指向i的符号表项的指针>
   <>=, _>
   <id, 指向j的符号表项的指针>
   <), _>
   <id, 指向i的符号表项的指针>
   <--, _>
   <;, _>
 
词法分析分析器作为一个独立子程序
词法分析是编译过程中的一个阶段,在语法分析前进行。词法分析作为一遍,可以简化设计,改进编译效率,增加编译系统的可移植性。也可以和语法分析结合在一起作为一遍,由语法分析程序调用词法分析程序来获得当前单词供语法分析使用。
正规表达式与正规集
正规表达式是说明单词的一种重要的表示法(记号),是定义正规集的工具。在词法分析中,正规表达式用来描述标示符可能具有的形式。
定义(正规式和它所表示的正规集):
设字母表为S,
1. e和Ø都是S上的正规式,它们所表示的正规集分别为{e}和{ };
2. 任何aÎ S,a是S上的一个正规式,它所表示的正规集为{a};
3. 假定U和V都是S上的正规式,它们所表示的正规集分别为L(U)和L(V),那么,(U), U|V, U·V, U*也都是正规式,它们所表示的正规集分别为L(U), L(U)ÈL(V), L(U)L(V)和(L(U))*;
4. 仅由有限次使用上述三步骤而定义的表达式才是S上的正规式,仅由这些正规式所表示的字集才是S上的正规集。
正规式的运算符的“½”读为“或” ,“· ”读为“连接”;“*”读为“闭包”(即,任意有限次的自重复连接)。
在不致混淆时,括号可省去,但规定算符的优先顺序为“(”、“)”、“*”、“· ”、“½” 。连接符“· ”一般可省略不写。
“*”、“· ”和“½” 都是左结合的。
例 令S={a,b}, S上的正规式和相应的正规集的例子有:
正规式                 正规集
a               {a}
a½b                    {a,b}
ab                       {ab}
(a½b)(a              {aa,ab,ba,bb}
a *                    {e ,a,a, ……任意个a的串}
ba*                                           {b, ba, baa, baaa, …}
(a½b)*                                      {e ,a,b,aa,ab ……所有由a和b
                                                  组成的串}
(a½b)*(aa½bb)(a½b)*               {S*上所有含有两个相继的a
                                                   或两个相继的b组成 的串}

关键字表package CompilePrograme;

import java.awt.List;
import java.util.Scanner;

public class Compile {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        double startTime = System.currentTimeMillis();
        final int MAX_LEN = 100;
        Scanner input = new Scanner(System.in);
        
        System.out.print("Please input a string <end with '#'>:");
        String uString = input.nextLine();
        input.close();

        String[] keyWords = new String[] { "begin", "if", "then", "while", "do", "end" };

        char[] analyseData = new char[MAX_LEN];

        int index = 0, key = 0;
        List list = new List();

        do {
            String compareStr = null;
            char temp = uString.charAt(index);
            list = extactCharacters(temp, analyseData, keyWords, uString, index, compareStr);
            if (list.getItemCount() == 0) {
                index++;
                continue;
            }
            // 规定List的第一个元素为index,第二个元素为key
            index = Integer.parseInt(list.getItem(0));
            key = Integer.parseInt(list.getItem(1));
            String words = list.getItem(2);
            System.out.println("< " + key + " ," + words + " >");
        } while (key != 0);
        double endTime = System.currentTimeMillis();
        System.out.println("\nProgram running time is :" + (endTime - startTime));
    }

    public static List extactCharacters(char temp, char[] analyseDate, String[] keywords, String uString, int index,
            String compareStr) {

        int keyID = -1, m = 0;
        // index--;
        List list = new List();
        // 1.判断下一个读入的字符是否为空格,用while作为大循环,若读取到空格则跳出方法,提取下一个字符进行判断
        while (temp != ' ') {
            // 2.判断当前字符是字母或者数字和字母的组合
            if (temp >= 'a' && temp <= 'z') {
                m = 0;

                // 当读取到不是大小写字母或者数字时候判断为一个单词读取完成
                while (temp >= 'a' && temp <= 'z' || temp >= 'A' && temp <= 'Z' || temp >= '0' && temp <= '9') {
                    analyseDate[m++] = temp;
                    compareStr += temp + "";
                    temp = uString.charAt(++index);
                }

                compareStr = compareStr.substring(4);
                // 与读取出来的字符判断是否为关键字
                for (int i = 0; i < 6; i++) {
                    if (compareStr.equals(keywords[i])) {
                        keyID = i + 1;
                        list.add(index + "");
                        list.add(keyID + "");
                        list.add(compareStr);
                        return list;
                    }
                }
                // 不是关键字就当作为标识符
                keyID = 10;
                list.add(index + "");
                list.add(keyID + "");
                list.add(compareStr);
                return list;
            }
            // 3,判断当前字符是数字?
            else if (temp >= '0' && temp <= '9') {
                m = 0;
                String tempTokens = null;
                // 对后面的字符进行判断是否为数字
                while (temp >= '0' && temp <= '9') {
                    analyseDate[m++] = temp;
                    tempTokens += temp;
                    temp = uString.charAt(++index);
                }
                // 不是数字则返回种别码,结束当前方法
                keyID = 11;
                tempTokens = tempTokens.substring(4);
                list.add(index + "");
                list.add(keyID + "");
                list.add(tempTokens + "");
                return list;
            }
            m = 0;
            // 4.判断当前字符是其他关系运算符
            String token = null;
            switch (temp) {
            case '<':
                // String token = null;
                analyseDate[m++] = temp;
                token += temp;
                if (uString.charAt(++index) == '=') {
                    analyseDate[m++] = temp;
                    keyID = 22;
                    token += uString.charAt(index++);
                } else if (uString.charAt(++index) == '>') {
                    analyseDate[m++] = temp;
                    keyID = 21;
                    token += uString.charAt(index++);
                } else {
                    keyID = 23;
                }
                list.add(index + "");
                list.add(keyID + "");
                token = token.substring(4);
                list.add(token);
                return list;
            case '>':
                // String tokens = null;
                analyseDate[m++] = temp;
                token += temp;
                if (uString.charAt(++index) == '=') {
                    keyID = 24;
                    analyseDate[m++] = temp;
                    token += uString.charAt(index++);
                } else {
                    keyID = 20;
                }
                list.add(index + "");
                list.add(keyID + "");
                token = token.substring(4);
                list.add(token);
                return list;
            case ':':

                analyseDate[m++] = temp;
                token += temp;
                if (uString.charAt(++index) == '=') {
                    keyID = 18;
                    // analyseDate[m++] = temp;
                    analyseDate[m++] = uString.charAt(index);
                    token += uString.charAt(index++);
                } else {
                    keyID = 17;
                }
                list.add(index + "");
                list.add(keyID + "");
                token = token.substring(4);
                list.add(token);
                return list;
            case '*':
                keyID = 13;
                break;
            case '/':
                keyID = 14;
                break;
            case '+':
                keyID = 15;
                break;
            case '-':
                keyID = 16;
                break;
            case '=':
                keyID = 25;
                break;
            case ';':
                keyID = 26;
                break;
            case '(':
                keyID = 27;
                break;
            case ')':
                keyID = 28;
                break;
            case '#':
                keyID = 0;
                break;
            default:
                keyID = -1;
                break;
            }
            analyseDate[m++] = temp;
            list.add(++index + "");
            list.add(keyID + "");
            list.add(temp + "");
            return list;
        }
        return list;
    }
}运行结果

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!