cnzym 发表于 2014-5-18 16:50:42

【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(觉得一定会很多……)或者有什么改进建议,欢迎指出~

Cursor 发表于 2014-5-18 16:52:37

看起来很厉害。。。(/ω\)

hikari.uiharu 发表于 2014-5-18 19:12:25

推荐《编程语言实现模式》,
比编译原理要实用一些

HHX-XXM 发表于 2014-5-18 19:26:36

直接链接成字节码?

cnzym 发表于 2014-5-18 20:43:06

HHX-XXM 发表于 2014-5-18 19:26
直接链接成字节码?

解释器而已

rourou_Jun 发表于 2014-5-19 00:31:27

Yuki这让我想到了酷市场的那只妹子

Nero 发表于 2014-5-19 11:28:13

把token用eval和apply两个函数互相递归来做会很方便地支持函数内的函数调用。
可以先看看SICP,算是最简单的一本讲语言解释的了。

HHX-XXM 发表于 2014-5-19 13:02:12

rourou_Jun 发表于 2014-5-19 00:31 static/image/common/back.gif
Yuki这让我想到了酷市场的那只妹子

我倒是想起了有希..是不是yuki来着

cnzym 发表于 2014-5-19 23:03:21

Nero 发表于 2014-5-19 11:28
把token用eval和apply两个函数互相递归来做会很方便地支持函数内的函数调用。
可以先看看SICP,算是最简单 ...

好的⊙▽⊙有时间了解一下

_14522 发表于 2014-5-23 18:04:53

楼主如果知道NOIP或者ACM的话,可以看看LRJ白书厚的那本有一组题,实现MUA
页: [1]
查看完整版本: 【YUKI】简单解释器而已…