How to handle qualified identifiers such as x.y in a Pascal-like language

noitalmost <noitalmost@cox.net>
Mon, 20 Jun 2011 15:43:24 -0400

          From comp.compilers

Related articles
How to handle qualified identifiers such as x.y in a Pascal-like langu noitalmost@cox.net (noitalmost) (2011-06-20)
Re: How to handle qualified identifiers such as x.y in a Pascal-like l torbenm@diku.dk (2011-06-22)
Re: How to handle qualified identifiers such as x.y in a Pascal-like l DrDiettrich1@aol.com (Hans-Peter Diettrich) (2011-06-22)
Re: How to handle qualified identifiers such as x.y in a Pascal-like l gene.ressler@gmail.com (Gene) (2011-06-22)
Re: How to handle qualified identifiers such as x.y in a Pascal-like l noitalmost@cox.net (noitalmost) (2011-06-23)
Re: How to handle qualified identifiers such as x.y in a Pascal-like l DrDiettrich1@aol.com (Hans-Peter Diettrich) (2011-06-24)
Re: How to handle qualified identifiers such as x.y in a Pascal-like l uu3kw29sb7@snkmail.com (\[Linux Magazine\]) (2011-06-24)
[14 later articles]
| List of all articles for this month |
From: noitalmost <noitalmost@cox.net>
Newsgroups: comp.compilers
Date: Mon, 20 Jun 2011 15:43:24 -0400
Organization: Compilers Central
Posted-Date: 22 Jun 2011 00:44:57 EDT

Here's a silly example program in my language syntax.
program P:
var x : int;


procedure s() :
var x : int;


procedure t() :
var x : int;
x := 3;
s.x := x + 10;
end t;


x := 2;
t();
P.x := x + 10;
end s;


x := 1;
s();
print x; # should output 23
end P.




I know how to handle the notation if the qualified identifier is a
record, since there's no change in the stack frame. It's just an
offset in the current frame.


What I don't quite understand is how to parse access to a variable in
an outer stack frame. And I think this is similar to the problem of
nested procedures (which I also don't quite know how to handle).


My parser is recursive descent and produces an AST. The AST consists
of nodes such as Program, ProcDef, VarDef, WhileStmt, AssignStmt,
Ident, Num, and ProcCall. The nodes ProcDef and VarDef are the nodes
in the symbol tables, while Ident represents an identifier as used in
a statement. Thus, an Ident node contains a pointer to a definition in
a symbol table. That definition has a field which gives an offset
relative to the current stack frame. A Program or a ProcDef contains a
symbol table and a list of code statements. The interpreter walks the
AST. When it encounters a node such as ProcDef, it creates a new stack
frame, uses the procedure's symbol table to allocate local variables,
and then walks its list of code statements.


So when I encounter
P.x := x + 10;
in the above program, I get an AST fragment something like
Assign( P.x, Add( x, 10) )
where x is an Ident and 10 is a Num. But what do I do with P.x? Should the
parser do all the work and make P.x simply an Ident (whose symTabEntry points
to the outermost x? Then Ident would need a frameCnt field so the interpreter
knows how many stack frames to back out of. In the above example, frameCnt
would be 1, while reference to a local variable would have frameCnt of 0.


Is this a reasonable way to approach the problem?
[Pretty much. The standard way to handle references to an enclosing
scope is with a display, the calling procedure passes the enclosing
stack frame addresses as hidden parameters. If your language doesn't
allow variable sized declarations or recursion, P.x will be at a fixed
distance below the current stack frame so you can address it directly,
but in a more general case, you need the display. See any 1970s
compiler text for details. -John]





Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.