Static (lexical) coverage and dynamic scaling (pseudo-code)

Program A() { x, y, z: integer; procedure B() { y: integer; y=0; x=z+1; z=y+2; } procedure C() { z: integer; procedure D() { x: integer; x = z + 1; y = x + 1; call B(); } z = 5; call D(); } x = 10; y = 11; z = 12; call C(); print x, y, z; } 

In my opinion, the result of this program when using static coverage is: x = 13, y = 7 and z = 2.

However, when it starts using dynamic coverage , the result is x = 10, y = 7, and z = 12.

These are the results that our professor gave us. However, I cannot understand how much he achieved these results. Can someone go through the pseudo-code and explain their meanings in two different types of areas?

+51
scope output pseudocode
Mar 14
source share
2 answers

With static (lexical) coverage, the structure of the program source code determines which variables you refer to. With dynamic reach , the execution state of the program stack determines which variable you are accessing. This is probably a very unfamiliar concept, since every programming language used today (except, perhaps, emacs lisp) uses a lexical domain, which is usually much easier for people and analysis tools to reason about.

Consider this simpler sample program (written in pseudo-code syntax):

 program a() { x: integer; // "x1" in discussions below x = 1; procedure b() { x = 2; // <-- which "x" do we write to? } procedure c() { x: integer; // "x2" in discussions below b(); } c(); print x; } 

The program and the compiler refer to both variables as x , but I have designated them x1 and x2 to simplify the discussion below.

With lexical coverage, we determine at compile time which x we mean based on the static lexical structure of the program source code. The innermost definition of x in the region where , defining b , x1 , and therefore the record in question is resolved to x1 and that where x = 2 written, so we print 2 when we run this program.

With dynamic scope, we have a stack of variable definitions tracked at runtime, so the x we write depends on what exactly is in scope and dynamically defined at runtime . Starting from a, a pushes x => x1 onto the stack, calling c pushes x => x2 onto the stack, and then when we go to b , the top of the stack is x => x2 , and so we write to x2 . This leaves x1 untouched, and so we print 1 at the end of the program.

Also, consider this slightly different program:

 program a() { x: integer; // "x1" in discussions below x = 1; procedure b() { x = 2; // <-- which "x" do we write to? } procedure c() { x: integer; // "x2" in discussions below b(); } c(); b(); } 

Note b is called twice - the first time through c , the second time directly. When using lexical coverage, the explanation above does not change, and we write x1 both times. However, with dynamic spanning, it depends on how x bound at runtime. The first time we call b , we write in x2 , as explained above, but the second time we write in x1 , since this is what is on top of the stack! ( x => x2 appears when c returned.)

So, here is your professor code annotated by using the exact variable on which the lexical domain is written. Entries ending at the end of the program are marked with * :

 program A() { x, y, z: integer; // x1, y1, z1 procedure B() { y: integer; // y2 y=0; // y2 = 0 x=z+1; // x1 = z1 + 1 = 12 + 1 = 13* z=y+2; // z1 = y2 + 2 = 0 + 2 = 2* } procedure C() { z: integer; // z2 procedure D() { x: integer; // x2 x = z + 1; // x2 = z2 + 1 = 5 + 1 = 6 y = x + 1; // y1 = x2 + 1 = 6 + 1 = 7* call B(); } z = 5; // z2 = 5 call D(); } x = 10; // x1 = 10 y = 11; // y1 = 11 z = 12; // z1 = 12 call C(); print x, y, z; // x1, y1, z1 } 

And here it is with dynamic coverage. Note that the changes are only in b and in the tag location * :

 program A() { x, y, z: integer; // x1, y1, z1 procedure B() { y: integer; // y2 y=0; // y2 = 0 x=z+1; // x2 = z2 + 1 = 5 + 1 = 6 z=y+2; // z2 = y2 + 2 = 0 + 2 = 2 } procedure C() { z: integer; // z2 procedure D() { x: integer; // x2 x = z + 1; // x2 = z2 + 1 = 5 + 1 = 6 y = x + 1; // y1 = x2 + 1 = 6 + 1 = 7* call B(); } z = 5; // z2 = 5 call D(); } x = 10; // x1 = 10* y = 11; // y1 = 11 z = 12; // z1 = 12* call C(); print x, y, z; } 
+151
Mar 14 '14 at 3:28
source share

Static scope and dynamic scaling are different ways of finding a specific variable with a specific unique name in a program written in any language.

This is especially useful for an interpreter or compiler to determine where and how to find a variable.

Consider the code as shown below

 f2(){ f1(){ } f3(){ f1() } } 

Static

This is basically a text value, the first variable is defined or will not be checked in the local function (let's call it f1 ()), if not in the local function f1 (), then the variable will be searched in the function f2 (), which ( this I have in mind f1 ()), ... this continues ... until a variable is found.

Dynamic:

This is different from static, in the sense that it is longer execution time or dynamic, the first variable is defined or will not be checked in the local function, if not in the local function f1 (), then the variable will look in the function f3 (), which is called this function (through this I mean f1 () again) ... this continues ... until a variable is found.

+8
Sep 07 '15 at 15:18
source share



All Articles