Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Exception 如何在具有goto或类似功能的组合语言解释器中实现Try/Except/Finally?_Exception_F#_Compiler Construction_Interpreter_Control Flow - Fatal编程技术网

Exception 如何在具有goto或类似功能的组合语言解释器中实现Try/Except/Finally?

Exception 如何在具有goto或类似功能的组合语言解释器中实现Try/Except/Finally?,exception,f#,compiler-construction,interpreter,control-flow,Exception,F#,Compiler Construction,Interpreter,Control Flow,如何在解释器上实现try/catch/finally功能(目前我使用的是F#) 我怀疑GOTO是可以使用的(但是,在解释器中为它提供功能也是必要的,不知道如何使用),但我一生中从未使用过GOTO(只知道GOTO是邪恶的!),也不知道如何保护环境 p.D:我已经知道CPS(Continuations)可以用来模拟异常和任何其他控制流。但是,这会使语言实现的其余部分变得复杂,需要通过优化来消除它的开销,对于这个问题,我希望了解其他实现方法 p.D.2:是否存在另一种替代CPS的方法,以便于实施定制控

如何在解释器上实现try/catch/finally功能(目前我使用的是F#)

我怀疑GOTO是可以使用的(但是,在解释器中为它提供功能也是必要的,不知道如何使用),但我一生中从未使用过GOTO(只知道GOTO是邪恶的!),也不知道如何保护环境

p.D:我已经知道CPS(Continuations)可以用来模拟异常和任何其他控制流。但是,这会使语言实现的其余部分变得复杂,需要通过优化来消除它的开销,对于这个问题,我希望了解其他实现方法

p.D.2:是否存在另一种替代CPS的方法,以便于实施定制控制流?或者一种通用GOTOs的方法?

控件可以通过多种方式摆脱“尝试”块:

  • 转到周围块中的标签(注意:转到X和转到Y是两种不同的转义!)
  • 从包含try的函数返回
  • 在try中抛出异常
  • 从try主体调用的函数传播异常
  • (可检测)在try正文中调用exit()
根据你的语言,你可能会有更多

try finally块必须做的是捕获所有这些,执行finally部分,然后继续预期的操作

实现这一点的一种方法是为每个街区逃生创建一个转移岛。转移岛作为每个行动的目标;如果控制装置到达转移岛K,则发生阻塞逃逸K。transfer island所做的是调用包含finally子句的(无参数)子例程,然后执行一个操作以继续转义K

设想以下try finally块:

   try
      ...goto X...  // ... means some control structure wrapped around this
      ...raise Z...
      ...call q()... // throws exception
      ...goto Y...
      ...return 5...
   finally
       <some actions>
   end
   ...return <exp>
试试看
…转到X…/。。。意味着围绕着它的一些控制结构
…升起Z。。。
…调用q()…//抛出异常
…去你的。。。
…返回5。。。
最后
结束
…返回
此代码可以编译为:

   // try
      ... goto  TIX...  // TIk ==> "tranfer island k"
      ...exception=Z; goto TIE ...
      ...try call q()
         catch exception; goto TIE
         end try 
      ...result=5; goto TIR...
    // finally
      local subroutine finally()
          { <some actions> }
      TIX: call finally();
           goto X;
      TIY: call finally();
           goto Y;
      TIR: call finally();
           goto RETURN;
      TIE: call finally();
           propagate exception;  // means "pass control to containing exception handler"
      ...
      // end try

           result=<exp>;
      RETURN:
           return result;
//试试看
... 转到TIX…//TIk==>“特兰弗岛k”
…异常=Z;去打领带。。。
…尝试呼叫q()
捕获异常;去打领带
结束尝试
…结果=5;转到TIR。。。
//最后
局部子程序finally()
{  }
提示:callfinally();
后藤X;
TIY:callfinally();
转到Y;
TIR:callfinally();
转到返回;
TIE:callfinally();
传播异常;//表示“将控制传递给包含异常处理程序”
...
//结束尝试
结果=;
返回:
返回结果;

在这种背景下,您必须使解释器执行操作,就好像此代码存在一样。显然,解释器不需要实例化转移岛;它知道发生了哪种类型的块转义,可以执行finally操作,然后继续执行块转义。

实际上没有人尝试/except/finally。它实际上是try/except和try/finally,它们可以嵌套在另一个中,例如(try(try exception)finally)。这使得处理起来更加容易。我不确定,但怀疑您可以在5.4节的错误中找到将代码翻译为F#at或F#at的使用信息。