分页: 1 / 1

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

发表于 : 2012-06-21 14:39
ee.zsy
拿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

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

发表于 : 2012-06-21 18:45
枫叶饭团
还是那句话,虽然看不懂,但是觉得好厉害 :em05 :em05

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

发表于 : 2012-06-21 18:48
jtshs256
果然id里带ee的都不是人

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

发表于 : 2012-06-21 18:49
月下叹逍遥
虽然看不懂,但是觉得好厉害

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

发表于 : 2012-06-22 1:20
ee.zsy
枫叶饭团 写了:还是那句话,虽然看不懂,但是觉得好厉害 :em05 :em05
最近随手点开一个日志似乎总能在下边看到饭团兄的评论,感觉真的好厉害了! :em01 :em01

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

发表于 : 2012-06-22 9:59
枫叶饭团
ee.zsy 写了:
枫叶饭团 写了:还是那句话,虽然看不懂,但是觉得好厉害 :em05 :em05
最近随手点开一个日志似乎总能在下边看到饭团兄的评论,感觉真的好厉害了! :em01 :em01
都是寂寞惹的货啊 :em18

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

发表于 : 2012-06-22 14:13
ee.zsy
枫叶饭团 写了:
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

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

发表于 : 2012-06-22 16:33
cjxgm
学习了
当初在 spoj 上刷 shorten 的题目(完成题目意思,谁的代码最短谁的排名最靠钱)就是靠 awk
可惜我只草草看过 man gawk,很多隐含规则都不了解……

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

发表于 : 2012-06-22 17:28
枫叶饭团
老是做些偶不懂的东西。。。继续复习期末考试

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

发表于 : 2012-06-22 19:11
noble_out
123454321

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

发表于 : 2012-06-23 14:31
wuzhaoyoung
AWK确实棒极了。文件处理能力太强大了!

学习中……