要实现一个用户自定义脚本来执行工作流程的功能。要支持一些时间函数 ,还有几个系统内实现了的操作硬件的函数。  我现在将流程写到XML文件中格式为<VAR 这里是自己定义的变量>
  <VAR NAME="@MenuCount" VARTYPE="Integer" VALUE="3"  CAPTION="主菜单循环计数"/>
  <VAR NAME="@DateTime"  VARTYPE="Date" VALUE="0" CAPTION="时间"/>
</VAR><BEGIN NAME="BEGIN" CAPTION="执行节点">
 <SET  LEFTNAME="@MenuCount:=week*(3+4)"/>
 <SET  LEFTNAME="@DateTime:=Date"/>
 <FUN  LEFTNAME="MYfun(@DateTime,True,True)"/>
 <IF  >
 <ELSE>
  
 </ELSE>
 </IF>
     
</BEGIN>格式如上,SET 节点是要给变量赋值。Fun 是执行一个自己定义的函数。
象 Week Now Date 这些不要参数可以立刻返回的函数都要以正常运行。
@MenuCount:=week*(3+4) 这样的表达式用后缀表达式的方式也可以正确计算和赋值现在的问题是不能支持函数的嵌套,如 Fun1(Fun2(true,123,Fun3(23)) 
因为不能正确的分解,用中置表达式到后缀表达式的方式不能分解这,
那位编译原理学的好,告诉一下 一般的编译器是如何分析我们写的代码的,怎么将函数的嵌套分解开一个个的执行。

解决方案 »

  1.   

    不是很难,就是比较罗嗦在解析表达式过程中遇到ID时要判断一下后续操作的类型,普通的运算符没什么说的,如果是括号就要做函数调用的处理,比如Fun1(a, b)这样的调用就要解析成
    [push a]
    [push b]
    [call func1, 2]
    在解析参数a, b的时候要递归表达式分解的过程,结束符为[',', ')']你举例的Fun1(Fun2(true,123,Fun3(23)) 可以解析为
    [push TRUE]
    [push 123]
    [push 23]
    [call func3, 1]
    [call func2, 3]
    [call func1, 1]我感觉你还没从整体上把握这个脚本必须要具备的特性,想想再继续做吧!
      

  2.   

    是呀,现在思路比较乱,这样的源代码分析应该是一门很成熟的技术也有对应的算法,我现在只是不知从什么地方下手,找资料也摸不到门。这应是算《编译原理》里面的内容吧??我现在是先将源代码一行行的读入,源代码的格式就是我上面的格式,这样流程就很好控制了。
    现在就是要分析每一行的表达式, 如果表达式组纯数字,或者是变量,或者是无括号的函数如Now,
    则用逆波兰表达式很容易将结果算出来,现在就是如果有嵌套的函数,就不好办了,
    逆波兰表达式无法分解计算了。楼上将  Fun1(Fun2(true,123,Fun3(23)) 分解为
    [push TRUE]
    [push 123]
    [push 23]
    [call func3, 1]
    [call func2, 3]
    [call func1, 1]前面的 push 就相当于 逆波兰表达式 的运算数吧
    从上向下扫描遇到 Call 就计算[call func3, 1] 的意思相当于是一个运算符弹出一个运算数进行计算,然后将结果重新压栈
    [call func2, 3] 是弹出三个运算数进行运算后结果压栈如果要能分解成这样子也就可以计算了。判断一下后续操作的类型 是什么意思??是指如果遇到 Fun1 就检查后面的数据类型应是什么样子吗?还有在分解时括号的对应关系也很不好搞。 谁知道分解的算法呀??好象要先分解成一棵树来着。
      

  3.   

    不要想的太复杂1. 将代码行分解为以符号EOL结尾的符号列表
    2. 分析表达式时必须设定结束标志,第一个肯定是EOL
    3. 表达式分解是个递归的过程,每次递归都要设定新的结束符号
    4. 函数调用表达式的结束符号是')'
    5. 参数表达式的结束符号是','和')'整体上必须做以下工作1. 建立全局变量堆栈
    2. 基于函数运行,函数在运行时要创建并维护自己的堆栈,允许定义局部变量
    3. 函数间允许嵌套调用,返回值能存入调用者的堆栈为简化开发可以1. 暂时只支持字符串一种变量
    2. 将函数调用平面化,不允许在表达式中出现函数调用
    3. 增加专用的函数调用语法,比如:
    <call:func_name into="@varible_name", param_count="1", param1="value1"/>
    函数返回值存入指定的临时变量