实验1《词法分析程序设计与实现》(java版)

第1关:词法分析程序设计与实现

任务描述

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

相关知识

为了完成本关任务,你需要掌握:词法分析程序设计与实现。

词法分析的基本知识

词法分析程序( Lexical analyzer,简称 Lexer ),负责从左到右逐个字符地对源程序进行扫描和分解,根据语言的词法规则识别出一个个的单词符号。

因此一个词法分析程序应具备如下功能:

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

  • 识别出有词法意义的单词

  • 返回单词记录,或词法错误信息

由上可知词法分析中的一个重要环节为识别单词符号类型,为了便于语法分析,通常将单词符号分为五类。

  • 标识符 用来命名程序中出现的变量、数组、函数、过程、标号等,通常是一个字母开头的字母数字串,如 length,nextch 等。

  • 基本字 也可以成为关键字或保留字。如 if,while,for,do,goto 等。他们具有标识符的形式,但他们不是由用户而是由语言定义的,其意义是约定的。多数语言中规定,他们不能作为标识符或者标识符的前缀,即用户不能使用它们来定义用户使用的名字,故我们称它为保留字,这些语言如 Pascal 和 C 等。但也有的语言允许将基本字作为标识符或者标识符的前缀,这类语言如 Fortran 等。

  • 常数 包括各种类型的常数,如整型、实型、字符型、布尔型等。如:53.1415926aTRUE等都是常数。

  • 运算符 算术运算符+-×÷;关系运算符<,<=,>,>=,==,!=以及逻辑运算符&&()||或者!等。

  • 界符 如等单字界符和/,/,//等双字界符,空白符等。

在进行词法分析后,识别出来的单词应该采用某种中间表示形式,以便为编译后续阶段方便地引用。通常一个单词用一个二元式来表示: (单词类别,单词的属性) 其中,第一元用于区分单词所属的类别,以整数编码表示。第二元用于区分该类别中的哪一个单词符号,即单词符号的值。

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

public class ex1 {
    /*
    * 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("/data/workspace/myshixun/input.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);
            }
        }
    }
	/********Beign********/
    /*数字的识别*/
    public static void digitCheck(String str){
        String token= String.valueOf(str.charAt(p++));
     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;
             }
         }
     } 
    }
    /********End********/

	/********Beign********/
    //标识符,关键字的识别
    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--;
        }
    }
    /********End********/

	/********Beign********/
    //符号的识别
    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");
            }
        }
}
	/********End********/

    //字符串检查
    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+")");
        }
    }
}

  • 8
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值