【YUKI】简单解释器而已…
本帖最后由 cnzym 于 2014-5-18 17:05 编辑高中时编写了一个简单的解释器,取名INF,功能特别弱。
现在大一,由于课程设计要求制作一个中缀式计算器,于是顺便写了一个解释器,取名YUKI。
INF解释器是用C语言编写的,有些功能的确难以在C语言条件下实现。由于大一系统地学习了C++,YUKI解释器采用了面向对象的编程思路,功能提高极大。但是……但是……我没有学过编译原理-_-|||,所以不要苛求太多^_-!
该解释器可以解释自创的过程式语言,其特性(或者说是缺陷)有:
——几乎没有错误提示(既然是解释器那就将就一下吧-_-||);
——支持自定义函数调用及其递归调用;
——内置若干种数学函数,以及功能可观的输出函数;
——由于希望将该解释器用MFC的方式实现,所以暂时没有设计输入语句;
——无数据类型(确切地说是均为double);
——变量有local和global两种存储类别;
——只支持一维数组;
——每个语句占一行,行尾无分号;
——支持空格缩进;
——不支持自定义函数调用中的函数调用(例如:func(1,func(2,3)));
——源代码文件末尾要加单独一行的“#”才能被正确读入;
……
今天将刚刚学习C语言时编写的简单日历C语言代码用Yuki重写,在该解释器中解释运行,效果如下:
其Yuki代码为:// 使用Yuki语言编写的一个简单日历
// 2014.5.18
// cnzym @ cnCalc.org
// 行输出
func:println(m,n)
{
local:i:=m
while(i<=n)
{
printNum(i)
print("")
i:=i+1
}
}
// 数字输出
func: printNum(x)
{
if( x>=1 && x<=9 )
{
print(" ",x)
}
else
{
if( x>=10 && x<=31 )
{
print(x)
}
else
{
print("xx")
}
}
}
func: printhln(start_index)
{
local:i:=1
while(i<=(start_index-1)*2)
{
print("")
i:=i+1
}
i:=1
while(i<=8-start_index)
{
printNum(i)
print("")
i:=i+1
}
}
func: pprint(start_index, md)
{
local:j:=0
printhln(start_index)
print("\n")
while(j<(md+(start_index-1))/7-2)
{
println(9-start_index+7*j,15-start_index+7*j)
print("\n")
j:=j+1
}
println(md-((md+start_index-1)%7)+1,md)
print("\n")
}
func:islpyr(y)
{
if(y%100!=0 && y%4==0)
{
return:1
}
if(y%100==0 && y%400==0)
{
return:1
}
if((y%4!=0 && y%100!=0)||(y%100==0 && y%400!=0))
{
return:0
}
}
func: mdays(m, y)
{
local:lp:=islpyr(y)
if(m==1)
{
return:31
}
if(m==3)
{
return:31
}
if(m==4)
{
return:30
}
if(m==5)
{
return:31
}
if(m==6)
{
return:30
}
if(m==7)
{
return:31
}
if(m==8)
{
return:31
}
if(m==9)
{
return:30
}
if(m==10)
{
return:30
}
if(m==11)
{
return:31
}
if(m==2 && lp==1)
return:29
if(m==2 && lp==0)
return:28
}
func:dsum(m,y)
{
local:ds:=0
local:j:=0
if(m>0)
{
j:=1
while(j<=m)
{
local:md:=mdays(j,y)
ds:=ds+md
j:=j+1
}
return:ds
}
if(m==0)
{
return:0
}
}
func:ydays(y)
{
local:lp:=islpyr(y)
if(lp==0)
{
return:365
}
if(lp==1)
{
return:366
}
}
func: week(y,m)
{
local:i:=0
local:dss:=1
if(y>2010)
{
i:=2010
while(i<y)
{
local:yd:=ydays(i)
dss:=dss+yd
i:=i+1
}
local:_dsum:=dsum(m-1,y)
dss:=dss+_dsum
local:a:=(dss-4)%7+1
return:(dss-4)%7+1
}
if(y<2010)
{
i:=y
while(i<=2009)
{
local:yd:=ydays(i)
dss:=dss+yd
i:=i+1
}
local:_dsum:=dsum(m-1,y)
dss:=dss-_dsum
if((dss-5)%7==0)
{
return:1
}
else
{
return:8-(dss-5)%7
}
}
if(y==2010)
{
if(m==1)
{
return:5
}
local:_dsum:=dsum(m-1,2010)
dss:=dss+_dsum
dss:=dss+1
return:(dss-4)%7
}
}
func: main()
{
local:year:=2014
local:month:=5
print("请注意:日历第一列是星期一!\n")
print(year, "年", month, "月\n")
local:wk:=week(year,month)
//print(wk, "\n")
local:md:=mdays(month,year)
print("==========================\n")
print("一二三四五六日\n")
print("==========================\n")
pprint(wk,md)
print("==========================\n")
#about
}
#
代码和几个例子在附件中,如果各位发现了bug(觉得一定会很多……)或者有什么改进建议,欢迎指出~
看起来很厉害。。。(/ω\) 推荐《编程语言实现模式》,
比编译原理要实用一些 直接链接成字节码? HHX-XXM 发表于 2014-5-18 19:26
直接链接成字节码?
解释器而已 Yuki这让我想到了酷市场的那只妹子 把token用eval和apply两个函数互相递归来做会很方便地支持函数内的函数调用。
可以先看看SICP,算是最简单的一本讲语言解释的了。 rourou_Jun 发表于 2014-5-19 00:31 static/image/common/back.gif
Yuki这让我想到了酷市场的那只妹子
我倒是想起了有希..是不是yuki来着 Nero 发表于 2014-5-19 11:28
把token用eval和apply两个函数互相递归来做会很方便地支持函数内的函数调用。
可以先看看SICP,算是最简单 ...
好的⊙▽⊙有时间了解一下 楼主如果知道NOIP或者ACM的话,可以看看LRJ白书厚的那本有一组题,实现MUA
页:
[1]