cnCalc计算器论坛 [原fx-es(ms)论坛]

 找回密码
 注册
搜索
查看: 1598|回复: 9

[其他] 【YUKI】简单解释器而已…

[复制链接]
发表于 2014-5-18 16:50:42 | 显示全部楼层 |阅读模式
本帖最后由 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代码为:
  1. // 使用Yuki语言编写的一个简单日历
  2. // 2014.5.18
  3. // cnzym @ cnCalc.org

  4. // 行输出
  5. func:println(m,n)
  6. {
  7.     local:i:=m
  8.     while(i<=n)
  9.     {
  10.         printNum(i)
  11.         print("  ")
  12.         i:=i+1
  13.     }
  14. }
  15. // 数字输出
  16. func: printNum(x)
  17. {
  18.     if( x>=1 && x<=9 )
  19.     {
  20.         print(" ",x)
  21.     }
  22.     else
  23.     {
  24.         if( x>=10 && x<=31 )
  25.         {
  26.             print(x)
  27.         }
  28.         else
  29.         {
  30.             print("xx")
  31.         }
  32.     }
  33. }
  34. func: printhln(start_index)
  35. {
  36.     local:i:=1
  37.     while(i<=(start_index-1)*2)
  38.     {
  39.         print("  ")
  40.         i:=i+1
  41.     }
  42.     i:=1
  43.     while(i<=8-start_index)
  44.     {
  45.         printNum(i)
  46.         print("  ")
  47.         i:=i+1
  48.     }
  49. }
  50. func: pprint(start_index, md)
  51. {
  52.     local:j:=0
  53.     printhln(start_index)
  54.     print("\n")
  55.     while(j<(md+(start_index-1))/7-2)
  56.     {
  57.         println(9-start_index+7*j,15-start_index+7*j)
  58.         print("\n")
  59.         j:=j+1
  60.     }
  61.     println(md-((md+start_index-1)%7)+1,md)
  62.     print("\n")
  63. }
  64. func:islpyr(y)
  65. {
  66.     if(y%100!=0 && y%4==0)
  67.     {
  68.         return:1
  69.     }
  70.     if(y%100==0 && y%400==0)
  71.     {
  72.         return:1
  73.     }
  74.     if((y%4!=0 && y%100!=0)||(y%100==0 && y%400!=0))
  75.     {
  76.         return:0
  77.     }
  78. }
  79. func: mdays(m, y)
  80. {
  81.     local:lp:=islpyr(y)
  82.     if(m==1)
  83.     {
  84.         return:31
  85.     }
  86.     if(m==3)
  87.     {
  88.         return:31
  89.     }
  90.     if(m==4)
  91.     {
  92.         return:30
  93.     }
  94.     if(m==5)
  95.     {
  96.         return:31
  97.     }
  98.     if(m==6)
  99.     {
  100.         return:30
  101.     }
  102.     if(m==7)
  103.     {
  104.         return:31
  105.     }
  106.     if(m==8)
  107.     {
  108.         return:31
  109.     }
  110.     if(m==9)
  111.     {
  112.         return:30
  113.     }
  114.     if(m==10)
  115.     {
  116.         return:30
  117.     }
  118.     if(m==11)
  119.     {
  120.         return:31
  121.     }
  122.     if(m==2 && lp==1)
  123.         return:29
  124.     if(m==2 && lp==0)
  125.         return:28
  126. }
  127. func:dsum(m,y)
  128. {
  129.     local:ds:=0
  130.     local:j:=0
  131.     if(m>0)
  132.     {
  133.         j:=1
  134.         while(j<=m)
  135.         {
  136.             local:md:=mdays(j,y)
  137.             ds:=ds+md
  138.             j:=j+1
  139.         }
  140.         return:ds
  141.     }
  142.     if(m==0)
  143.     {
  144.         return:0
  145.     }
  146. }
  147. func:ydays(y)
  148. {
  149.     local:lp:=islpyr(y)
  150.     if(lp==0)
  151.     {
  152.         return:365
  153.     }
  154.     if(lp==1)
  155.     {
  156.         return:366
  157.     }
  158. }

  159. func: week(y,m)
  160. {
  161.     local:i:=0
  162.     local:dss:=1
  163.     if(y>2010)
  164.     {
  165.         i:=2010
  166.         while(i<y)
  167.         {
  168.             local:yd:=ydays(i)
  169.             dss:=dss+yd
  170.             i:=i+1
  171.         }
  172.         local:_dsum:=dsum(m-1,y)
  173.         dss:=dss+_dsum
  174.         local:a:=(dss-4)%7+1
  175.         return:(dss-4)%7+1
  176.     }
  177.     if(y<2010)
  178.     {
  179.         i:=y
  180.         while(i<=2009)
  181.         {
  182.             local:yd:=ydays(i)
  183.             dss:=dss+yd
  184.             i:=i+1
  185.         }
  186.         local:_dsum:=dsum(m-1,y)
  187.         dss:=dss-_dsum
  188.         if((dss-5)%7==0)
  189.         {
  190.             return:1
  191.         }
  192.         else
  193.         {
  194.             return:8-(dss-5)%7
  195.         }
  196.     }
  197.     if(y==2010)
  198.     {
  199.         if(m==1)
  200.         {
  201.             return:5
  202.         }
  203.         local:_dsum:=dsum(m-1,2010)
  204.         dss:=dss+_dsum
  205.         dss:=dss+1
  206.         return:(dss-4)%7
  207.     }
  208. }

  209. func: main()
  210. {
  211.     local:year:=2014
  212.     local:month:=5
  213.     print("请注意:日历第一列是星期一!\n")
  214.     print(year, "年", month, "月\n")
  215.     local:wk:=week(year,month)
  216.     //print(wk, "\n")
  217.     local:md:=mdays(month,year)
  218.     print("==========================\n")
  219.     print("一  二  三  四  五  六  日\n")
  220.     print("==========================\n")
  221.     pprint(wk,md)
  222.     print("==========================\n")
  223.     #about
  224. }
  225. #
复制代码
代码和几个例子在附件中,如果各位发现了bug(觉得一定会很多……)或者有什么改进建议,欢迎指出~

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
发表于 2014-5-18 16:52:37 | 显示全部楼层
看起来很厉害。。。(/ω\)
发表于 2014-5-18 19:12:25 | 显示全部楼层
推荐《编程语言实现模式》,
比编译原理要实用一些
发表于 2014-5-18 19:26:36 | 显示全部楼层
直接链接成字节码?
 楼主| 发表于 2014-5-18 20:43:06 来自手机 | 显示全部楼层
HHX-XXM 发表于 2014-5-18 19:26
直接链接成字节码?

解释器而已
发表于 2014-5-19 00:31:27 来自手机 | 显示全部楼层
Yuki  这让我想到了酷市场的那只妹子
发表于 2014-5-19 11:28:13 | 显示全部楼层
把token用eval和apply两个函数互相递归来做会很方便地支持函数内的函数调用。
可以先看看SICP,算是最简单的一本讲语言解释的了。
发表于 2014-5-19 13:02:12 | 显示全部楼层
rourou_Jun 发表于 2014-5-19 00:31
Yuki  这让我想到了酷市场的那只妹子

我倒是想起了有希..是不是yuki来着
 楼主| 发表于 2014-5-19 23:03:21 来自手机 | 显示全部楼层
Nero 发表于 2014-5-19 11:28
把token用eval和apply两个函数互相递归来做会很方便地支持函数内的函数调用。
可以先看看SICP,算是最简单 ...

好的⊙▽⊙有时间了解一下
发表于 2014-5-23 18:04:53 | 显示全部楼层
楼主如果知道NOIP或者ACM的话,可以看看LRJ白书厚的那本有一组题,实现MUA
您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|Archiver|手机版|cnCalc计算器论坛  

GMT+8, 2019-1-18 18:04 , Processed in 0.089989 second(s), 20 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表