Born to be proud
4/28
2016

词法分析器

编译原理实验课写的词法分析器,加深了对编程语言的理解,将课本上的伪代码实现完善了一遍,纯手打。

/* 编译原理实验-词法分析器
 * 刘嘉琦-20160325
 * 1、PL/0语言的单词结构
//关键字(10个):begin, end ,if ,then, while, do, const, var,call,procedure
//标识符:字母序列,最大长度10
//常数:整型常数
//算符和界符(17个):+, -, *,/,odd,=,<>,<,>,<=,>=,:=,(,) ,, ,.,;
//2、单词的种别划分
//    标识符 作为一种
//    常数 作为一种
//    算符和界符每个单词作为一个单独种别
//3、PL/0的语言的词法分析器将要完成以下工作:
//(1)    跳过分隔符(如空格,回车,制表符);
//(2)    识别诸如begin,end,if,while等保留字;
//(3)    识别非保留字的一般标识符。
//(4)    识别数字序列。
//(5)    识别:=,<=,>=之类的特殊符号。
//4、词法分析器的实现方式:
//    把词法分析器设计成一个独立子程序,以便于语法分析器调用。词法分析器运行一次产生一个单词符号。
//5、词法分析器的输出形式
//   (种别,属性值)
//其中:种别在“2、单词的种别”中进行了定义;
//      属性值:若单词种别只代表唯一单词,属性值为空;
//              若单词种别是SYM_IDENTIFIER,属性值为该单词在标识符表中的位置;
//              若单词种别是SYM_ NUMBER,属性值为该单词在常数表中的位置。
**/
package foc;

import java.util.Scanner;

public class cffxq {
    char ch;
    StringBuffer strToken;
    static int flag_getchar = 0; //搜索指示器
    String str;   //字符串
    String[] gjz = {"odd","begin", "end" ,"if" ,"then", "while", "do", "const", "var","call","procedure"};
    String[][] chart_id = new String[100][2];
    int flag_id = 0; //标识符指针
    String[] chart_const = new String[100];
    int flag_const = 0; //常数指针

    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        StringBuffer stb = new StringBuffer(sc.nextLine());
        stb.append(" ");
        String str = stb.toString();
        cffxq c = new cffxq();
        while(flag_getchar<str.length()-1){
            c.begin(str);
        }

    }

    private void GetChar(){
        ch = str.charAt(flag_getchar);
        flag_getchar++;
    } 

    public void begin(String str) {
        this.str = str;

        int code,value;
        strToken = new StringBuffer("");
        GetChar();
        GetBC();
        if(IsLetter()){
            while(IsLetter()||IsDigit()){
                Concat();
                GetChar();
            }
            Retract();
            code = Reserve();
            if(code < 0){
                value = InsertId(strToken.toString());
                System.out.println("($ID," + value +")");
                return;
            }
            else if(code == 0){
                System.out.println("(算符或界符," + "odd"+")"); 
                return;
            }
            else{
                System.out.println("($"+gjz[code]+",-)" ); 
                return;
            }
        }

        else if(IsDigit()){
            while(IsDigit()){
                Concat();
                GetChar();
            }
            Retract();
            value = InsertConst(strToken.toString());
            System.out.println("($INT," + value +")");
            return;
        }

        else if(ch == '+'){
            System.out.println("($+," + "-)");
            return;
        }
        else if(ch == '-'){
            System.out.println("($-," + "-)");
            return;
        }
        else if(ch == '*'){
            System.out.println("($*," + "-)");
            return;
        }
        else if(ch == '/'){
            System.out.println("($/," + "-)");
            return;
        }
        else if(ch == '='){
            System.out.println("($=," + "-)");
            return;
        }
        else if(ch == ','){
            System.out.println("($,," + "-)");
            return;
        }
        else if(ch == '.'){
            System.out.println("($.," + "-)");
            return;
        }
        else if(ch == '('){
            System.out.println("($(," + "-)");
            return;
        }
        else if(ch == ')'){
            System.out.println("($)," + "-)");
            return;
        }
        else if(ch == ';'){
            System.out.println("($;," + "-)");
            return;
        }
        else if(ch == ':'){
            GetChar();
            if(ch == '='){
                System.out.println("($:=," + "-)");
                return;
            }
            Retract();
            System.out.println("($:," + "-)");
        }
        else if(ch == '>'){
            GetChar();
            if(ch == '='){
                System.out.println("($>=," + "-)");
                return;
            }
            Retract();
            System.out.println("($>," + "-)");
            return;
        }
        else if(ch == '<'){
            GetChar();
            if(ch == '>'){
                System.out.println("($<>," + "-)");
                return;
            }
            else if(ch == '='){
                System.out.println("($<=," + "-)");
                return;
            }
            Retract();
            System.out.println("($<," + "-)");
            return;
        }

    }

    private void GetBC(){
        if(ch==' '){
            GetChar();
            GetBC();
        }
    }

    private void Concat(){
        strToken.append(ch);
    }

    private boolean IsLetter(){
        if(Character.isLetter(ch))
            return true;
        else
            return false;
    } 

    private boolean IsDigit(){
        if(Character.isDigit(ch))
            return true;
        else
            return false;
    } 

    private int Reserve(){
        for(int i=0;i<gjz.length; i++){
            if(gjz[i].equals(strToken.toString()))
                return i;
        }
        return -1;   //返回数组索引,否则返回-1
    }

    private void Retract(){
        flag_getchar--;
        ch = ' ';
    }

    private int InsertId(String strToken){
        for(int i=0;i<flag_id;i++){
            if(chart_id[i][0].equals(strToken))
                return i;
        }
        chart_id[flag_id][0] = strToken;
        flag_id++;
        return flag_id-1;
    }

    private int InsertConst(String strToken){
        for(int i=0;i<flag_const;i++){
            if(chart_const[i].equals(strToken))
                return i;
        }
        chart_const[flag_const] = strToken;
        flag_const++;
        return flag_const-1;
    }
    private void ProcError(){
        System.out.println("词法错误!");
    }

}