词法分析器简单实现

1. 何为词法分析器?
将一段源程序转换为一个一个的单词符号.
2. 关于单词符号及其分类?
1>  关键字(保留字):是一类具有特殊意义的标识符.如java中的if,else...
2>  标识符:自己规定的具有特定含义的词。如变量名,数组名,类名称,方法名.
3>  常数:一般包括整型,实型,布尔类型,文字类型。如100,3.1415,true,’simple’...
4>  运算符:+,-,*,/等等.
5>  界符:如逗号,分号,括号,/*  */等等.
3. 关于词法分析器的输出格式?
常用该二元式表示:(单词类别,单词符号的属性值).
  * 单词类别:通常用整数进行编码,用来区分单词类型。
  * 单词符号的属性:在上述中如果一个单词类别只包含一个单词,那么只需单词类别就可以表示自身,但如果含有多个单词的话,那么除了单词类别,还需要该单词符号的特有信息,称为单词符号的属性.

不同的单词的单词符号属性值:
  * 标识符:常用存放它有关信息符号的指针作为其值。
  * 常数:常数类似,用存放常数的指针来表示.

对于一符一种的,只给出种别编码.
下面是代码实现:
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

public class Online {
    public static char ch = ' '; //用于存放最新读入的字符.
    public static String strToken = "";//用于存储构造单词符号(常数,标示符,关键字等等...)
    public static int flag = 0;//用于标注下次读取的字符位置.
    // 保留字(关键字)表
    public static Map<String, Integer> map = new HashMap<String, Integer>();
    //用来接收标识符的数组.
    public static String[] Id = new String[200];
    public static int f1 = 0;
    //用来接收常数的数组.
    public static String[] Const = new String[200];
    public static int f2 = 0;

    // map初始化
    public void start() {
        map.put("if", 1);
        map.put("else", 2);
        map.put("int", 3);
        map.put("char", 4);
        map.put("float", 5);
    }

    //每次读入一个字符并保存到ch中.
    public void GetChar(String str) {
        ch = str.charAt(flag);
        flag++;
    }
    //判断ch是否为空白字符,如果是的话,则循环读取直至读到不为空白的字符,将其赋给ch
    public void GetBC(String str) {
        while (Character.isSpaceChar(ch)) {
            GetChar(str);
        }
    }
    //将ch中的字符连接到strToken后
    public void Concat() {
        strToken += ch;
    }

    public boolean IsLetter() // 是否为字母
    {
        if (Character.isLetter(ch)) {
            return true;
        }
        return false;
    }
    // 是否为数字
    public boolean IsDigit() 
    {
        if (Character.isDigit(ch)) {
            return true;
        }
        return false;
    }
    //判断strToken是否为关键字,如是,返回种别编码(不从0开始),否则返回0.
    public int Reserve() {
        start();
        Set<String> set = map.keySet();
        for (String str : set) {
            if (str.equals(strToken)) {
                return map.get(strToken);
            }
        }
        return 0;
    }
    //进行回退操作
    public void Retract() {
        flag--;
        ch = ' ';
    }

    // 将标识符插入符号表
    public int InsertId() {
        Id[f1] = strToken;
        f1++;
        return f1 - 1;
    }
    // 将常数插入常数表
    public int InsertConst() {
        Const[f2] = strToken;
        strToken = "";
        f2++;
        return f2 - 1;
    }

    public static void myPrint(String code, String value) {
        System.out.println("<" + code + "," + value + ">");
    }

    public void test(String str) {
        int code; // 单词符号的种别编码
        int value; // 单词符号的属性值或无定义
        while (flag < str.length()) {
            GetChar(str);
            GetBC(str);
            if (IsLetter()) {
                // 为防止取字符越界.
                while (IsDigit() || IsLetter()) {
                    Concat();
                    if (flag < str.length()) {
                        GetChar(str);
                    } else {
                        break;
                    }
                }
                System.out.println(strToken);
                code = Reserve();
                // 需要考虑最后一位与前边是否一致,如一致则不回退,否则进行回退.
                //当最后一位为字母时,无需进行回退.
                if (!IsDigit() && !IsLetter()) {
                    Retract(); // 多读,进行回退.
                }
                if (code == 0) {
                    value = InsertId();
                    myPrint("id", "" + value); // 标识符
                } else {
                    myPrint("key", "" + code); // 关键字
                }
                strToken = "";
            } else if (IsDigit()) {
                while (IsDigit()) {
                    Concat();
                    GetChar(str);
                }
                value = InsertConst();
                Retract();
                myPrint("number", "" + value);
            } else {
                switch (ch) {
                case '=':
                    myPrint("=", "-");
                    break;
                case '(':
                    myPrint("(", "-");
                    break;
                case ')':
                    myPrint(")", "-");
                    break;
                case '{':
                    myPrint("{", "-");
                    break;
                case '}':
                    myPrint("}", "-");
                    break;
                default:
                    System.out.println("ERROR!");
                }
            }
        }

    }

    public static void main(String[] args) {
        System.out.println("please input :");
        Scanner scan = new Scanner(System.in);
        String str = scan.nextLine();
        Online on=new Online();
        on.test(str);
    }
}
本代码只实现了一行代码的分析,可以根据IO操作从文件中每次读取一行进行处理,从而实现文件的词法分析处理。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值