标签:1.0 obj 函数调用 正文 main 类型信息 词法 入门 语义
# HelloWorld.ice
print("hello, world")
其实从开始学习编译原理到现在已经有快半年的时间了,但是其间常常不能坚持看下去龙书(经常三天打鱼两天晒网,更何况每次打鱼不到半小时就累得不行又会放下书(笑)),截至到现在只勉强看完了前六章的部分,半年间其它事也没有做,其实想想上大学已经快两年了还是一事无成,知识也没有学到,不免觉得很羞愧。
暑假也要到了,这个学期马上也要结束了,临近大二结束之际,还是尝试着写一下以前想写的玩具吧,而本系列就是对这段过程的记录,也算是对龙书前六部分的一个小实践&总结(后面的部分可能看完了我也写不出什么东西来)。
其实再写这个解释器之前,我是拿lex + yacc + llvm照着tutorial试着拼过一个编译器,但是llvm对我来说可能有些太难了(苦笑)。残破不堪的代码在lyli分支上。
这个系列的教程(如果可以算作教程的话),其实主要还是实现了前端部分(一样有很多bug),而parser早就被研究透了,所以本教程基本上没有什么价值,可能唯一具有优势的地方就是我跟愿意看这几篇文章的读者大概是相同的入门(或者还未入门)的水平。
本教程分为四章
且希望能达到在读者阅读完本系列后,能完成一个支持以下几项的解释器语言
在正式手撸之前,我们要先确立我们要撸的是个什么玩意儿(你这不是废话吗摔)。毕竟在后期想要增加一些新的骚操作(新特性)的时候,若没有在一开始进行设计,难免会出现各种重构上令人烦躁的问题(虽然如果你按照本教程撸出来的解释器必然会带来重构上各种糟糕的问题,但是重构本身就是一件会带来各种糟糕的问题的事情(所以就不要介意了)),但是在正式写代码之前进行设计,总是一件应该做的事。
从解释器角度来说,我们解释的是字符串,在验证字符串满足规则后进行解释,在解释完之后将其按照语义正确执行,而这个规则就是我们Ice的语法规则。
从词法分析器的角度来说,我们解释是字符串,只需要输入的字符串满足我们为词素指定的规则,然后根据输入的字符串返回token给语法分析器就可以了。
从语法分析的角度来说,我们解释的是token序列,且通过预测分析法依据token序列选择正确的产生式并返回抽象语法树(Abstract Syntax Tree)。
只考虑交互式输入(即一行一行的输入)
本项目中主要包含以下几个类:
好了,基本上结构就是这样,下面可以着手考虑Ice具备怎么样的语法了。
1
1.0
"hello, world"
1 + 1
(100 + 20) * 6 / 3
10 = 10
5 <= 3
@a: 1
@add(a, b): a + b
@mul(a, b)
{
return a * b
}
mul(mul(2, 3), add(2, 3))
@fib(n)
{
if (n = 0) + (n = 1)
{
return 1
}
else
{
return fib(n-1) + fib(n-2)
}
}
fib(10) # 89
@a: 3
while a
{
print(a)
@a: a - 1
}
@a: 0
do {
@a: a + 1
if a = 3
{
break
}
print(a)
} while a < 5
for 1 to 5
{
@a: a + 1
if a = 3
{
continue
}
print(a)
}
@add(a, b): a + b
@mul: @(a, b){
return a * b
}
@(a, b){ return a / b }(9, 3)
@quadraticSum: @(a, b){
@sqrt: @(n){ return n * n }
return @(a, b){ return a + b }(sqrt(a), sqrt(b))
}
基本上就是这样,那么如果你还继续打算看的话,下一章将会开始手撸Ice的词法分析器。
标签:1.0 obj 函数调用 正文 main 类型信息 词法 入门 语义
原文地址:https://www.cnblogs.com/Mu001999/p/8965745.html