Next: About this document ...
Computer Science 5220
Spring 2002
Exam 2
Instructions. Answer all of the questions. For the multiple-choice
questions, circle the letter of the best answer, even if no
answer is ideal.
- How would a live variable analysis be useful in generating
good quality executable code?
- It can help to avoid generating instructions to store
some values from registers into memory.
- It allows you to use more registers to hold
temporary values.
- A live variable analysis makes it unnecessary to perform
a control flow analysis.
- A live variable analysis is useful in finding
places where
variables might be used before they are defined.
- Which of the following would be least likely to be
stored in the symbol table of a compiler?
- The type of an identifier.
- The location where an identifier will be stored.
- The type of a complex expression.
- The number of bytes required for a particular,
named type.
- Some compilers work by building data structures called
syntax trees that describe relevant information about a component
of a program, such as an expression or statement. A
syntax tree
- is almost always identical in structure to a parse tree.
- often differs substantially from a parse tree.
- is not stored explicitly in the memory, but is
traversed implicitly during the parsing process.
- is usually considered an inefficient way to perform
translations, and should be avoided.
- Inherited attributes are difficult to use in a bottom-up
parser because
- The parser cannot handle ambiguous grammars.
- The parser does not build an explicit parse tree.
- The parser only makes one bottom-up pass over the
parse tree.
- The parser only makes one top-down pass over the
parse tree.
- In a Pascal compiler, types of expressions can be inferred
- as a synthesized attribute of expression nonterminal.
- as an inherited attribute of expression nonterminals.
- by looking in the symbol table, without using attributes.
- by asking the lexer to determine type information.
- A basic block is a useful concept for code
generation because
- Basic blocks are required for dataflow analysis.
- Basic blocks are required for control flow analysis.
- The compiler would not be able to assign registers without
using basic blocks.
- The compiler can generate code for a basic block as a
sequence of instructions without concern for branching.
- Assume that and are global variables of type integer,
where is at offset 1 and is at offset 2. Write a translation
of expression into code for the abstract
machine used in your Pascal compiler project. The code should
compute the value of this expression and store the result
onto the stack. Only show the code that might be
generated by your compiler. It is not important that you
use the exact correct names of instructions, but use names that
make the intended instruction clear.
- A programming language has a kind of expression
called a booleanExpression. The following productions describe
them.
A booleanExpression has two inherited attributes, called
true and false, where .true is a label number where
the program should jump if is true, and .false is the
label where the program should jump if is false.
Write semantic actions to compile boolean expressions into
the byte code that you used for your Pascal compiler.
Just write the semantic actions in a clear form, being sure
to define the inherited attributes where necessary.
Assume that all variables are global variables of type integer.
Function get_var_offset(x) tells the offset where global variable
x is stored.
- You are given the following grammar for variable declarations
in a programming language.
for example, declaration
declares , and to have type integer. The lexical analyzer
produces the name of an identifier (a string) for an identifier,
and the parser produces a data structure that describes a type
as the attribute of a type.
A function insert(name,type) is available
that makes an entry in the symbol table indicating that
the type of variable name is type, where name
is a string and type is the same kind of thing that is
produced as the attribute of the type nonterminal.
You would like to make entries into the symbol table that are
called for by a given declaration. Modify the grammar (without
changing the language) so that only synthesized
attributes are needed. Write the grammar with semantic actions
in Bison syntax so that the necessary symbol table entries
get done. Your new nonterminals can have attributes. Do
not use any global variables. (Hint: think about what the
parse tree should look like so that information only needs
to flow up the tree.)
Next: About this document ...
Karl R. Abrahamson
2002-04-30