程序设计语言问题,过程语言,动态范围



我在我的软件开发课程中被分配了这样一个问题。因此,通常的方法是逐个检查每个过程并记住每个子程序的每个调用,然而,我是一个有点懒惰的程序员,我决定采取捷径,通过在实际的编程语言中实现给定的伪代码。

问题陈述:

procedure Main is
X, Y, Z : Integer;
procedure Sub1 is
A, Y, Z : Integer;
begin
...
end;
procedure Sub2 is
A, B, Z : Integer;
begin
...
procedure Sub4 is
A, B, W : Integer;
begin
...
end;
end;
procedure Sub3 is
A, X, W : Integer;
begin
...
end;
begin
...
end;
考虑上面的程序。给定下面的调用序列,并假设使用动态作用域,在执行最后一个子程序期间,哪些变量是可见的激活吗?在每个可见变量中包含声明它的单元名(例如Main.X)。
  • 主调用Sub1;Sub1调用Sub3;Sub3呼叫Sub2;

我的尝试:

$x = 10;
$y = 20;
$z = 30;
sub Sub2 
{ 
return $x; 
}
sub Sub1
{ 
local $x = 9; 
local $y = 19; 
local $z = 29; 
return Sub2(); 
}
print Sub1()."n";

我被困在这一点上,不知道如何改变代码,使它显示我的变量。我认为这个解决方案是显而易见的,但到目前为止,我已经用c++和Java编写了代码。

如果你把问这个问题的时间花在看教程上就好了。然而,我们都有过这样的经历,在探索新语言时感到困惑。下次尽量不要问你作业的答案。

所以,我看到你想用Perl,一个很好的选择。我自己最近也做了一个类似的任务,下面是我的方法。

R. Sebesta(2019)在名为"编程概念"的书中写道Languages"(12版),动态作用域的最佳示例是Perl和Common Lisp。

基本上,它基于只在运行时确定的子程序调用序列。

下面的程序展示了子程序调用如何影响变量值:

$x = 0;
$y = 0;
$z = 0;
sub sub1
{
local $a = 1;
local $y = 1;
local $z = 1;
return sub3();
}
sub sub2
{
local $a = 2;
local $b = 2;
local $z = 2;
sub sub4
{
local $a = 4;
local $b = 4;
local $w = 4;
}
return "Sub".$a.".A, "."Sub".$b.".B, "."Sub".$w.".W, "."Sub".$x.".X,
"."Sub".$y.".Y, "."Sub".$z.".Z";

}
sub sub3
{
local $a = 3;
local $x = 3;
local $w = 3;
return sub2();
}
print sub1()."n";

:Sub2.BSub2.ASub3.WSub3.XSub1.Y,Sub2.Z
注意:Sub0只是Main子程序作用域。

如果您想检查每个子程序中变量的值,您可以使用Data::DumpData::Dumper等模块将它们转储。

sub foo { 
printf "foo() current values are %snn", 
Data::Dumper::Dumper($a, $b, $c, $x, $y, $z);
}

如果你想看到当前子程序的调用堆栈,你可以使用Carp模块。

use Carp;
sub foo { Carp::cluck("foo() here"); }
sub bar { foo() }
&bar;
# Output
foo() here at (eval 284) line 1.
W::foo() called at (eval 284) line 1
W::bar() called at (eval 285) line 1
eval 'package W; bar' called at script.pl line 116
console::_console called at script.pl line 473

最新更新