实现词法分析器

实验内容要求

一、实验目的 加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程 语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分 析。

二、实验内容 自定义一种程序设计语言,或者选择已有的一种高级语言,编制它的词法分析程序。词 法分析程序的实现可以采用任何一种编程语言和编程工具。 从输入的源程序中,识别出各个具有独立意义的单词,即关键字、标识符、常数、运算 符、界符。并依次输出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“Error”, 然后跳过错误部分继续显示)

三、实验要求: 1. 对单词的构词规则有明确的定义; 2. 编写的分析程序能够正确识别源程序中的单词符号; 3. 识别出的单词以<种别码,值>的形式保存在符号表中,正确设计和维护符号表; 4. 对于源程序中的词法错误,能够做出简单的错误处理,给出简单的错误提示,保 证顺利完成整个源程序的词法分析;

四、实验步骤 1. 定义目标语言的可用符号表和构词规则; 2. 依次读入源程序符号,对源程序进行单词切分和识别,直到源程序结束; 3. 对正确的单词,按照它的种别以<种别码,值>的形式保存在符号表中; 4. 对不正确的单词,做出错误处理。

实验方法

根据对应的状态转换图完成编码就可以了,内容我不详细多说,下面的图可以作为参照,实际上还需要自己去思考更多,我的代码还是存在一点小问题的,仅供大家参考。

java 分词新词发现关键词抽取情感分析摘要文本相似度文本分类 java实现词法分析器_System

import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;

public class LexicalAnalyzer {
    /*
    * 1表示关键字
    * 2表示标识符
    * 3表示常数
    * 4表示运算符
    * 5表示界符
    * 6表示字符串
    * */

    //关键字
    static String []keyWord={"private","protected","public","abstract","class","extends","final","implements",
            "interface","native","new","static","strictfp","break","continue","return","do","while","if","else","for",
            "instanceof","switch","case","default","boolean","byte","char","double","float","int","long","short",
            "String","null","true","false","void","this","goto"};
    //运算符
    static String []operation={"+","-","*","/","%","++","--","-=","*=","/=","&","|","^","~","<<",">>",">>>","==","!=",
            ">","<","=",">=","<=","&&","||","!","."};
    //界符
    static String []symbol={",",";",":","(",")","{","}"};
    static ArrayList<String> keyWords=null;
    static ArrayList<String> operations=null;
    static ArrayList<String> symbols=null;

    //指向当前所读到字符串的位置的指针
    static int p,lines;


    public static void main(String []args) throws FileNotFoundException {
        init();
        File file=new File("E:\\code\\bytest\\test11\\test2.txt");
        lines=1;
        try(Scanner input=new Scanner(file)) {
            while (input.hasNextLine()){
                String str=input.nextLine();
                analyze(str);
                lines++;
            }
        }

    }

    //初始化把数组转换为ArrayList
    public static void init(){
        keyWords=new ArrayList<>();
        operations=new ArrayList<>();
        symbols=new ArrayList<>();
        Collections.addAll(keyWords, keyWord);
        Collections.addAll(operations, operation);
        Collections.addAll(symbols, symbol);
    }

    public static void analyze(String str){

        p=0;
        char ch;
        str=str.trim();
        for (;p<str.length();p++){
            ch=str.charAt(p);
            if (Character.isDigit(ch)){
                digitCheck(str);
            }else if (Character.isLetter(ch)||ch=='_'){
                letterCheck(str);
            }else if (ch=='"'){
                stringCheck(str);
            }
            else if (ch==' '){
                continue;
            }else {
                symbolCheck(str);
            }
        }
    }

    /*数字的识别
    * 1、识别退出:
    *   1.1、遇到空格符
    *   1.2、遇到运算符或者界符
    * 2、错误情况:
    *   2.1、两个及以上小数点
    *   2.2、掺杂字母
    * */
    public static void digitCheck(String str){
        String token= String.valueOf(str.charAt(p++));
        //判断数字的小数点是否有且是否大于1
        int flag=0;
        boolean err=false;
        char ch;
        for (;p<str.length();p++) {
            ch = str.charAt(p);
            if (ch==' '||(!Character.isLetterOrDigit(ch)&&ch!='.')) {
                break;
            }else if (err){
                token+=ch;
            }
            else {
                token+=ch;
                if (ch == '.') {
                    if (flag == 1) {
                        err = true;
                    } else {
                        flag++;
                    }
                }else if (Character.isLetter(ch)){
                    err=true;
                }
            }
        }
        if (token.charAt(token.length()-1)=='.'){
            err=true;
        }
        if (err){
            System.out.println(lines+"line"+": "+token+" is wrong");
        }else {
            System.out.println("("+3+","+token+")");
        }
        if (p!=str.length()-1||(p==str.length()-1&&!Character.isDigit(str.charAt(p)))){
            p--;
        }
    }

    //标识符,关键字的识别
    public static void letterCheck(String str){
        String token= String.valueOf(str.charAt(p++));
        char ch;
        for (;p<str.length();p++){
            ch=str.charAt(p);
            if (!Character.isLetterOrDigit(ch)&&ch!='_'){
                break;
            }else{
                token+=ch;
            }
        }
        if (keyWords.contains(token)){
            System.out.println("("+1+","+token+")");
        }else {
            System.out.println("("+2+","+token+")");
        }
        if (p!=str.length()-1||(p==str.length()-1&&(!Character.isLetterOrDigit(str.charAt(p))&&str.charAt(p)!='_'))){
            p--;
        }
    }

    //符号的识别
    public static void symbolCheck(String str){
        String token= String.valueOf(str.charAt(p++));
        char ch;
        if (symbols.contains(token)){
            System.out.println("("+5+","+token+")");
            p--;
        }else {
            if (operations.contains(token)){
                if (p<str.length()){
                    ch=str.charAt(p);
                    if (operations.contains(token+ch)){
                        token+=ch;
                        p++;
                        if (p<str.length()){
                            ch=str.charAt(p);
                            if (operations.contains(token+ch)){
                                token+=ch;
                                System.out.println("("+4+","+token+")");
                            }else{
                                p--;
                                System.out.println("("+4+","+token+")");
                            }
                        }else{
                            System.out.println("("+4+","+token+")");
                        }
                    }else {
                        p--;
                        System.out.println("("+4+","+token+")");
                    }
                }
            }else {
                p--;
                System.out.println(lines+"line"+": "+token+" is wrong");
            }
        }
    }

    //字符串检查
    public static void stringCheck(String str){
        String token= String.valueOf(str.charAt(p++));
        char ch;
        for (;p<str.length();p++){
            ch=str.charAt(p);
            token+=ch;
            if (ch=='"'){
                break;
            }
        }
        if (token.charAt(token.length()-1)!='"'){
            System.out.println(lines+"line"+": "+token+" is wrong");
        }else {
            System.out.println("("+6+","+token+")");
        }
    }
}

实验结果

1、对于正确的输入:

public static void test(){
        int a=10;
        double b=20.2;
        double c=a+b;
    }

java 分词新词发现关键词抽取情感分析摘要文本相似度文本分类 java实现词法分析器_java_02


2、有不正确的输入:

public static double test(){
        double a=20.3.2.1;
        int 1111bbbb=10;
        System.out.println(a+b);
        String str="helloWorld";
        double c=124.、
        a++;
        return a+b+c;
    }

java 分词新词发现关键词抽取情感分析摘要文本相似度文本分类 java实现词法分析器_源程序_03


java 分词新词发现关键词抽取情感分析摘要文本相似度文本分类 java实现词法分析器_java_04