[怀旧]拿'AWK'第六章的代码改了一个BASIC语言解释器出来汗

sh/bash/dash/ksh/zsh等Shell脚本
回复
头像
ee.zsy
帖子: 41
注册时间: 2010-05-09 16:10
来自: 微风的河岸
联系:

[怀旧]拿'AWK'第六章的代码改了一个BASIC语言解释器出来汗

#1

帖子 ee.zsy » 2012-06-21 14:39

拿AWK写的,最近感觉AWK真的是好厉害的工具。
:em03


放在github/gist上的代码地址:
+ 代码 http://gist.github.com/2959816
+ 测试 http://gist.github.com/2959877
总之就这么慢慢地陆陆续续地会再再做点修改吧。
如果当前的版本是坏掉的,有可能前一个版本是好的。
当前只是直接根据代码的字符串来运行就是了,这样不大好就是了。
:em06


功能是按照GWBASIC做的,实现得很不完整就是了。
看看上面的那个测试代码的链接就能看到能做什么了。
:em11


用法什么大致是这样的:
+ 一行一个语句,行内语句可以用冒号分割;
+ 每行可以有行号,或者当行用“label:”的设置标签;
+ goto语句用来跳转到行号或标签;
+ gosub跳转后遇到return会返回;
+ if跳转语句 if 1<2 and 2<2+1 goto 10;
+ 单行if-then语句可以直接接代码;
+ while/wend为循环语句,可以嵌套使用;
+ rem语句,单行注释;
+ print语句显示,末尾分号“;”表示不换行;
+ input语句,从键盘输入行,input ">",x或input x;
+ cls清除屏幕;
+ let x=1 用来给变量赋值,let可以省略;
+ end语句,结束程序;
+ 可以使用数组“x[1]=2”;
+ 内置函数提供 mod、len……;
+ 运算符有 &(字符串连接) +(数字求和) - * / = and or ;
+

补充说明:
+ 以#和@开头的行被作为保留用途了,比如#开头的行当注释处理了,
+ 尽量保障mawk能运行,不行的话请用gawk
+

潜在的问题:
+ 数字1/0有时会被判为逻辑假/真(逻辑表达式貌似没有问题),
+ 测试很不充分,仅保障当前自带的示例代码能运行。
+
:em20


原书上的代码是 http://cm.bell-labs.com/cm/cs/who/bwk/awkcode.txt
这里是拿里面文件名为 awk.parser 的这个代码改的,改动不是很大。
就这样吧
:em02
头像
枫叶饭团
帖子: 14683
注册时间: 2010-06-16 1:05
系统: Mac OS X
来自: Tencent
联系:

Re: [怀旧]拿'AWK'第六章的代码改了一个BASIC语言解释器出来汗

#2

帖子 枫叶饭团 » 2012-06-21 18:45

还是那句话,虽然看不懂,但是觉得好厉害 :em05 :em05
jtshs256
帖子: 22323
注册时间: 2010-07-19 21:41
系统: OS X

Re: [怀旧]拿'AWK'第六章的代码改了一个BASIC语言解释器出来汗

#3

帖子 jtshs256 » 2012-06-21 18:48

果然id里带ee的都不是人
躺平
头像
月下叹逍遥
论坛版主
帖子: 33994
注册时间: 2010-10-07 14:23
系统: Archdows10
来自: 某系某星某洲某国某省某市
联系:

Re: [怀旧]拿'AWK'第六章的代码改了一个BASIC语言解释器出来汗

#4

帖子 月下叹逍遥 » 2012-06-21 18:49

虽然看不懂,但是觉得好厉害
浮生七十今三十,从此凄惶未可知
头像
ee.zsy
帖子: 41
注册时间: 2010-05-09 16:10
来自: 微风的河岸
联系:

Re: [怀旧]拿'AWK'第六章的代码改了一个BASIC语言解释器出来汗

#5

帖子 ee.zsy » 2012-06-22 1:20

枫叶饭团 写了:还是那句话,虽然看不懂,但是觉得好厉害 :em05 :em05
最近随手点开一个日志似乎总能在下边看到饭团兄的评论,感觉真的好厉害了! :em01 :em01
头像
枫叶饭团
帖子: 14683
注册时间: 2010-06-16 1:05
系统: Mac OS X
来自: Tencent
联系:

Re: [怀旧]拿'AWK'第六章的代码改了一个BASIC语言解释器出来汗

#6

帖子 枫叶饭团 » 2012-06-22 9:59

ee.zsy 写了:
枫叶饭团 写了:还是那句话,虽然看不懂,但是觉得好厉害 :em05 :em05
最近随手点开一个日志似乎总能在下边看到饭团兄的评论,感觉真的好厉害了! :em01 :em01
都是寂寞惹的货啊 :em18
头像
ee.zsy
帖子: 41
注册时间: 2010-05-09 16:10
来自: 微风的河岸
联系:

Re: [怀旧]拿'AWK'第六章的代码改了一个BASIC语言解释器出来汗

#7

帖子 ee.zsy » 2012-06-22 14:13

枫叶饭团 写了:
ee.zsy 写了:
枫叶饭团 写了:还是那句话,虽然看不懂,但是觉得好厉害 :em05 :em05
最近随手点开一个日志似乎总能在下边看到饭团兄的评论,感觉真的好厉害了! :em01 :em01
都是寂寞惹的货啊 :em18
寂寞就来版聊吧,最近发现awk真的是个太好玩的东西了。
像咱这种对写shell脚本不熟的人来说,觉得awk真的很有用。


比如一些常见的命令都可以用awk实现:

代码: 全选

cat          awk '{print}'
nl           awk '{print NR,$0}'
去行号       awk '{sub(/^[0-9]+ /,"");print}' 
wc -l        awk 'END{print NR}' 
sort         awk '{A[NR]=$0}END{asort(x);for(i=1;i<=NR;i++)print A[ i]}'
echo         awk 'BEGIN{for(i=1;i<ARGC;i++)printf("%s ",ARGV[i]);print}'
uniq         awk '!A[$0]++'

也可以当计算器用:

代码: 全选

计算均值
awk '{S+=$0}END{print S/NR}'
另一种写法
awk 'BEGIN{for(i=1;i<ARGC;i++)s+=ARGV[ i];print s/(ARGC-1)}'
或者交互地计算表达式
awk '{gsub(/[^0-9()*/+-]/,"");sprintf("awk \"BEGIN{print %s}\"",$0)|getline;print}'

或者可以做GUI:

代码: 全选

#!/usr/bin/gawk -f
BEGIN{
    "zenity --title \"Question\" --entry --text \"Your name?\""|getline;
    gsub(/\"/,"\\\"");gsub(/\\/,"\\\\\\");
    sprintf("zenity --info --text \"Hello, %s!\"",$0)|getline;
    print;
}

或者可写HttpServer,然后浏览器访问“http://127.0.0.1:8080”:

代码: 全选

#!/usr/bin/gawk -f
BEGIN{
    port = "/inet/tcp/8080/0/0";
    while(1){
        print "HTTP/1.1 200 OK" |& port;
        print "" |& port;
        print "Hello World!" |& port;
        while ((port |& getline) > 0 && !/^\r$/)
            print;
        close(port);
    }
}

可以实现常见的数据结构,比如最简单Stack可以这样:
用数组——

代码: 全选

#!/usr/bin/gawk -f
BEGIN{
    push(1);
    push(2);
    print pop();
    push(3);
    print pop();
    print pop();
    print pop();
}
function push(x){
     stack[++stack["top"]] = x;
}
function pop(    x){
    if(stack["top"]==0){
        print "<underflow>"
        return;        
    }
    x = stack[stack["top"]--]
    return x
}
用链表——

代码: 全选

#!/usr/bin/gawk -f
BEGIN{
    push(1);
    push(2);
    print pop();
    push(3);
    print pop();
    print pop();
    print pop();
}
function push(x){
    n++;
    node_next[n] = list_head;
    node_data[n] = x;
    list_head = n;
}
function pop(    p,x){
    if(!list_head){
        print "<underflow>"
        return;
    }
    x = node_data[list_head];
    p = node_next[list_head];
    delete node_data[list_head];
    delete node_next[list_head];
    list_head = p;
    return x
}
或者链表——

代码: 全选

#!/usr/bin/gawk -f
BEGIN{
    push(1);
    push(2);
    print pop();
    push(3);
    print pop();
    print pop();
    print pop();
}
function push(x){
    n++;
    list[n,"next"] = list["head"];
    list[n,"data"] = x;
    list["head"] = n;
}
function pop(    p,x){
    if(!list["head"]){
        print "<underflow>"
        return;
    }
    x = list[list["head"],"data"];
    p = list[list["head"],"next"];
    delete list[list["head"],"data"];
    delete list[list["head"],"next"];
    list["head"] = p;
    return x
}

亦或者可以像顶楼里那样,
用正则表达式做词法解析,
用递归函数写递归下降的LL(1)文法解析器,
写写最简单的解释器或编译器应该都能使的。

:em11


咱这才是都是寂寞惹的货啊 :em18
头像
cjxgm
帖子: 1952
注册时间: 2010-04-23 20:40
系统: Arch Linux
来自: 浙江·杭州
联系:

Re: [怀旧]拿'AWK'第六章的代码改了一个BASIC语言解释器出来汗

#8

帖子 cjxgm » 2012-06-22 16:33

学习了
当初在 spoj 上刷 shorten 的题目(完成题目意思,谁的代码最短谁的排名最靠钱)就是靠 awk
可惜我只草草看过 man gawk,很多隐含规则都不了解……
Clanjor Prods. | Develop for Developers. (C++, Lua) | 作曲编曲 | 实时渲染引擎
头像
枫叶饭团
帖子: 14683
注册时间: 2010-06-16 1:05
系统: Mac OS X
来自: Tencent
联系:

Re: [怀旧]拿'AWK'第六章的代码改了一个BASIC语言解释器出来汗

#9

帖子 枫叶饭团 » 2012-06-22 17:28

老是做些偶不懂的东西。。。继续复习期末考试
头像
noble_out
帖子: 150
注册时间: 2012-04-20 15:58
系统: ubuntu12.04+windows8
来自: 中华人民共和国
联系:

Re: [怀旧]拿'AWK'第六章的代码改了一个BASIC语言解释器出来汗

#10

帖子 noble_out » 2012-06-22 19:11

123454321
头像
wuzhaoyoung
帖子: 80
注册时间: 2007-08-05 21:58
来自: 浙江杭州+台州

Re: [怀旧]拿'AWK'第六章的代码改了一个BASIC语言解释器出来汗

#11

帖子 wuzhaoyoung » 2012-06-23 14:31

AWK确实棒极了。文件处理能力太强大了!

学习中……
回复