分享

自己动手写basic解释器(三)

 quasiceo 2014-01-02
分类: Unix/Linux Programming 2008-09-14 19:44 1258人阅读 评论(0) 收藏 举报

自己动手写basic解释器

刺猬@http://blog.csdn.net/littlehedgehog

 





注: 文章basic解释源码摘自梁肇新先生的《编程高手箴言》(据他所说这个代码也是网上摘录的),源码解读参考《java编程艺术》。《java编程艺术》里面自然是java版了(可能旭哥更加适合点儿),我这里还是解读的C版basic解释器代码。




经过get_token,我们可以获取一个标识符,按理说来下步可以进行程序逻辑处理了,但是标识符获取后我们离后面的真正程序逻辑运行还有一个大障碍,这就是表达式求解的问题。 比如说我们遇到一条语句    PRINT  3*(a+b)这里print 倒是能识别是个关键字,我们按照程序逻辑应该打印后面的东东,是字符串就直接打印,是变量就取值打印,但是这里偏偏是一个表达式,我们需要事先计算出表达式的值。接下来的问题就演变成了如何计算一个表达式,或者说写一个四则运算器。

关于如何写四则运算器,网上相关资料很多,源代码里的函数我没有解读,主要是看着不爽,逻辑性不够。再者这个东西其实我大一自学数据结构的时候写过,主要思想是建立二叉树,然后类似一个中序遍历即可。这里稍作解释,具体代码分析就不写了。大家可以参照我原来的博客《四则运算》《重言式判别》。

我们策略是设置运算符权值,具体规则是设置初始权值为0,扫描整个表达式,遇到+ - 号权值加1,赋给当前运算符号,遇到乘除号,权值加2,赋值;遇到乘方号,权值加3,赋值;遇到左括号,权值加4,遇到右括号,权值减4。 比如
3+3*(4-2)  初始权值赋值为0  第一个加号,加上1,赋给加号。第二个乘号权值加上2,权值为2(注意前面权值加一只是为了赋值,本身不变),赋给乘号。后面遇到左括号,权值本身再加4,这时权值为4,但是这里不赋值,因为括号不参与运算,当然这只是我这里图方便,你说要赋值也不是不可,就是后面麻烦点儿。马上又是减号,权值加1赋值,减号的权值变5,接着是右括号,权值减4。所以整个下来有
3+3*(4-2)    表达式
   1   2  5       权值

权值分析完毕,然后就是找出最小权值的一个符号,作为二叉树的根,权值越大的越往下生长,叶子节点全是数字。然后递归遍历解决。我原来那个程序只能计算表达式,但其实稍作改动就能计算变量了。在此不再赘述。下面贴出计算核心代码:
  1. double calculator(binarytree *root)
  2. {
  3.     if(root)
  4.     {
  5.         if(root->left==NULL&&root->right==NULL)
  6.             return atof(&root->data);
  7.         else 
  8.         {
  9.             switch(root->data)
  10.            {
  11.             case '*':
  12.                 return calculator(root->left)*calculator(root->right);
  13.                 break;
  14.             case '/':
  15.                 return calculator(root->left)/calculator(root->right);
  16.                 break;
  17.             case '+':
  18.                 return calculator(root->left)+calculator(root->right);
  19.                 break;
  20.             case '-':
  21.                 return calculator(root->left)-calculator(root->right);
  22.                 break;
  23.             case '^':
  24.                 return pow(calculator(root->left),calculator(root->right));
  25.             default:
  26.                 break;
  27.             }
  28.         }
  29.     }
  30. }

经过表达式求解函数get_exp(value)处理后,我们就得到这个表达式的值了。这样,万事具备,就等着程序的逻辑处理.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多