词法分析器代码已上传到个人资源中。
当我们的程序源文件进入编译器,首先遇到的就是词法分析器。
词法分析器的作用就是解析源文件,分析出其中的词素,并把这个词素的顺序集输入给语法分析器。
接上篇把所谓的词素也就是终结符号列出来:
if else while ( ) { } cpreop bitop logiop armtcop number literal id NUL new [ ] basetype class private public static return break continue . this
其中cprop包括 > < >= <= == != 即比较运算符
bitop 为位运算符,包括<< >> & | ^
logiop 逻辑运算符 包括 && ||
armtcop 算数运算符 包括 + - * /
number 数字常量 例如12345整形火 1.2345小数
id 标识符 按java规则
literal 字符串常量 如"ROgerwong"
NUL 空串
basetype 基本类型 包括 int char double 三种
当然,为了简单,在这里并不打算讨论非确定有穷自动机和确定有穷自动机的理论以及其之间的转换算法,只是用最朴素的方法,不断的将字符读入缓冲区,然后和这些词素进行比较,然后把这个词素加入到一个ArrayList中。按着这个方法定义几个数据结构:
定义词素数据结构,共含两个域,1个表示类型,一个表示具体的值,类型的取值也已经标出。
package ravaComplier.lexer;
public class Lexeme {
public int type;
public Object value;
public Lexeme(int t,Object v)
{
type=t;
value=v;
}
@Override
public String toString()
{
return new String("<"+type+":"+value.toString()+">");
}
public static int IF=0;//if
public static int ELSE=1;//else
public static int WHILE=2;//while
public static int BRACKET=3;//各种括号
public static int CPREOP=4;//比较符号
public static int BITOP=5;//位操作符
public static int LOGIOP=6;//逻辑运算符
public static int ARMTOP=7;//算术运算符
public static int NUMBER=8;//立即数
public static int LITERAL=9;//字符串
public static int ID=10;//id
public static int NUL=11;//空
public static int NEW=12;//new 操作符
public static int BASETYPE=13;//基本数据类型
public static int CLASS=14;//关键字class
public static int ACCESSFLAG=15;//public 或者private
public static int STATIC=16;//关键字static
public static int RETURN=17;//关键字return
public static int BREAK=18;//break
public static int CONTINUE=19;//continue
public static int DOT=