前言
你知道吗,在《编译原理》的附录上,有一个简单的java实现的编译器前端,由源码生成三地址码!虽然我不会去写java这种辣鸡语言就是了,但是我看到其中词法分析器真的好简单,比我做的suatin-lexer用正则表达式分割的还要简单啊。
定义token
//token
#define space 0 //空格或者\t
#define eol 1 //\n
#define eq 2 //=
#define lt 3 //<
#define gt 4 //>
#define plus 5 //+
#define minus 6 //-
#define star 7 // *
#define slash 8 // /
#define lp 9 //(
#define rp 10 //)
#define comma 11 //,
#define number 12 //8字节浮点数,字面量
#define string 13 //字符串,字面量
#define identifier 14 //标识符,字面量
#define if 15 //if, 0和""表示假,其他表示真
#define while 16 //while
#define and 17 //and
#define or 18 //or
#define not 19 //not
#define def 20 //def
#define ret 21 //ret
定义结构体
//token
struct tk{
int t; //token类型
int i; //字面量在符号表中的索引
};
//symbol table unit
struct symbol{
int literal_type; //字面量类型
union {
double d;
char* s;
}value;
int type; //标识符值类型
char* name;
unsigned int hash; //当然要根据hash值查找标识符啊,这也算不得复杂!
};
//lexer
struct lexer{
struct tk* tklist[2048];
struct symbol* symlist[512]; //符号表
};
BNF
statement := identifier '=' expression '\n' |
expression '\n' |
functioncall '\n' |
functiondef '\n' |
ifblock '\n' |
whileblock '\n'
identifier := <all characters which isnot keyword
and front symbol isnot operator> 支持中文变量
expression := expression ('+' | '-' | '*' | '/' | 'and' | 'or') expression |
'not' expression |
'(' expression ')' |
identifier
functioncall:= 'def' ' ' identifier '(' [identifier] {',' identifier } ')'
'\n' block
functiondef := identifier '(' [expression ] {',' expression} ')'
ifblock := 'if' ' ' expression '\n' block
whileblock := 'while' ' ' expression '\n' block
block := {statement}
不知道缩进怎么用BNF表示
例子
print是buildin中函数
a = 12.3
b = 34
c = "hello"
if a and b > 34 or c == 2
print("hello")
i = 0
while i < 100
print(i,">",a)
a = a/2
i=i+1
def saynumber(a,b)
print(a,b)
ret a + b
c = saynumber(a,b)
实现
~ 略 ~
等我把现在做的这个i think of you编译器做到生成字节码后,再精简做成这个tiny编程语言!