Presentation is loading. Please wait.

Presentation is loading. Please wait.

6. Semantic Analysis. Semantic Analysis Phase – Purpose: compute additional information needed for compilation that is beyond the capabilities of Context-

Similar presentations


Presentation on theme: "6. Semantic Analysis. Semantic Analysis Phase – Purpose: compute additional information needed for compilation that is beyond the capabilities of Context-"— Presentation transcript:

1 6. Semantic Analysis

2 Semantic Analysis Phase – Purpose: compute additional information needed for compilation that is beyond the capabilities of Context- Free Grammars and Standard Parsing Algorithms – Static semantic analysis: Take place prior to execution (Such as building a symbol table performing type inference and type checking) Classification – Analysis of a program required by the rules of the programming language to establish its correctness and to guarantee proper execution – Analysis performed by a compiler to enhance the efficiency of execution of the translated program

3 Description of the static semantic analysis – Attribute grammar identify attributes of language entities that must be computed and to write attribute equations or semantic rules that express how the computation of such attributes is related to the grammar rules of the language. – Which is most useful for languages that obey the principle of Syntax-Directed Semantics – Abstract syntax as represented by an abstract syntax tree

4 Contents 6.1 Attributes and Attribute Grammars 6.3 The Symbol Table 6.4 Data Types and Type Checking

5 6.1 Attributes and Attribute Grammars

6 Attributes – Any property of a programming language construct such as The data type of a variable The value of an expression The location of a variable in memory The object code of a procedure The number of significant digits in a number Binding of the attribute – The process of computing an attribute and associating its computed value with the language construct Binding time – The time during the compilation/execution process when the binding of an attribute occurs – Based on the difference of the binding time, attributes is divided into Static attributes (be bound prior to execution) and Dynamic attributes (be bound during execution)

7 Example: The binding time and significance during compilation of the attributes. – Attribute computations are extremely varied – Type checker A Type Checker is a semantic analyzer that computes the data type attribute of all language entities for which data types are defined and verifies that these types conform to the type rules of the language. In a language like C or Pascal, is an important part of semantic analysis;. While in a language like LISP, data types are dynamic, LISP compiler must generate code to compute types and perform type checking during program execution. – The values of expressions Usually dynamic and the be computed during execution; But sometime can also be evaluated during compilation (constant folding).

8 6.1.1 Attribute Grammars

9 In syntax-directed semantics, attributes are associated directly with the grammar symbols of the language. X.a means the value of ‘ a ’ associated to ‘ X ’ – X is a grammar symbol and a is an attribute associated to X Syntax-directed semantics: – Attributes are associated directly with the grammar symbols of the language. – Given a collection of attributes a 1, …, a k, it implies that for each grammar rule X 0  X 1 X 2 … X n (X 0 is a nonterminal), – The values of the attributes X i.a j of each grammar symbol X i are related to the values of the attributes of the other symbols in the rule.

10 An attribute grammar for attributes a 1, a 2, …,a k is the collection of all attribute equations or semantic rules of the following form, – for all the grammar rules of the language. Xi.aj = f ij (X 0.a 1, …,X 0.a k, …,X 1.a l,….. X 1.a k …, X n-1.a 1, … X n.a k ) Where f ij is a mathematical function of its arguments Typically, attribute grammars are written in tabular form as follows: Grammar Rule Semantic Rules Rule 1 Associated attribute equations... Rule n Associated attribute equation

11 Example 6.1 consider the following simple grammar for unsigned numbers: Number  number digit | digit Digit  0|1|2|3|4|5|6|7|8|9 The most significant attribute: numeric value (write as val), and the responding attribute grammar is as follows:

12 The parse tree showing attribute computations for the number 345 is given as follows

13 Example 6.2 consider the following grammar for simple integer arithmetic expressions: Exp  exp + term | exp-term | term Term  term*factor | factor Factor  (exp)| number The principal attribute of an exp (or term or factor) is its numeric value (write as val) and the attribute equations for the val attribute are given as follows

14 Given the expression (34-3)*42, the computations implied by this attribute grammar by attaching equations to nodes in a parse tree is as follows

15 Example 6.3 consider the following simple grammar of variable declarations in a C-like syntax: Decl  type var-list Type  int | float Var-list  id, var-list |id Define a data type attribute for the variables given by the identifiers in a declaration and write equations expressing how the data type attribute is related to the type of the declaration as follows: (We use the name dtype to distinguish the attribute from the nonterminal type)

16 Note that there is no equation involving the dtype of the nonterminal decl. It is not necessary for the value of an attribute to be specified for all grammar symbols Parse tree for the string float x,y showing the dtype attribute as specified by the attribute grammar above is as follows:

17 Example 6.4 consider the following grammar, where numbers may be octal or decimal, suppose this is indicated by a one-character suffix o(for octal) or d(for decimal): Based-num  num basechar Basechar  o|d Num  num digit | digit Digit  0|1|2|3|4|5|6|7|8|9 In this case num and digit require a new attribute base, which is used to compute the val attribute. The attribute grammar for base and val is given as follows.

18

19 345o

20 6.3 Symbol Table

21 The symbol table is the major inherited attribute in a compiler and, after syntax tree, forms the major data structure. The operations of the Symbol table are insert: is used to store the information provided by name declarations when processing these declarations. lookup: is needed to retrieve the information associated to a name when that name is used to associate code delete: is needed to remove the information provided by a declaration when that declaration no longer applies

22 The structure of the symbol table The symbol table in a compiler is a typical dictionary data structure include linear lists :constant time insert operations, can be chosen if speed is not a concern various search tree structures( binary search trees, AVL trees, B trees):do not provide best case efficiency and complexity of delete operations hash tables: best choice because all three operations can be performed at constant time.

23 The best scheme for compiler construction is to open addressing, called separate chaining. In this method each bucket is actually a linear list, and collisions are resolved by inserting the new item into the bucket list.

24 separate chaining. – The size of the linear list ranges from few hundred to over a thousand – Size of the bucket array should be chosen to be a prime number. Hash function for a symbol table – Convert the character string in to an integer between 0…..size-1 Convert each character in to a non negative integer – C language uses ASCII values – Pascal uses ord function Combine all the integers in to a single integer – Programmers choice Resulting integer should be scaled to the range of 0……size-1

25 separate chaining. – Mod function is used to scale a number to fall in to the range of 0…size-1. – Combine all the integers in to a single integer One simple method is to consider first few characters or first middle and last characters and ignore the rest – Inadequate: as programmers can use variables like temp1,temp2… and will cause frequent collisions Chosen method should reduce the collisions One good method is to multiplying factor(some constant number ) – If ci is the numeric value of the (i+1)th character and hi is the partial is the partial hash value computed at the (i)th step then » h(i+1) = h i +c » This can be generalized to » H=( n-1 c 1 + n-2 c 2 +……. c n-1 +c n )mod size

26 separate chaining – The choice of the constant in this formula has significant effect on the out come A reasonable choice for the constant is a number which is power of 2 (like 2,4,8,16,32,64,128…)

27 Declarations. – There is no specific standard to create a symbol table for all compilers. Symbol table will vary from compiler to compiler and it depends on – How each compiler Calls insert and delete operations – How the variables are declared in each compiler. – How long the compiler wants the symbol table to exist – The behavior of the symbol table heavily depends on the properties of declarations of the language being translated. – There are 4 basic kinds of declarations Constant, – Const int SIZE=199 type – Structures and unions variable – Variable declarations :int a,b[100]

28 Declarations. – procedure/function Are constant declaration of procedure/function type (similar to other variables) These variables are explicit in nature (needs to be declared before use) In few compliers they are implicit in nature (need not be declared before use) – Fortran,basic – We can create one single symbol table for all above 4 declarations Constant declarations(value binding) associate values to names. – Saves them in the symbol table and their value will never change in symbol table – In the execution phase the compiler will change these constant variables names to values by picking them from the symbol table

29 Declarations. – We can create one single symbol table for all above 4 declarations – Type declarations, Variable declaration and function/procedure declarations also will be saved in the symbol table with minute difference between each other

30 Scope rules and Block structure: In the above program there are five blocks First block : Variables int i,j and the function f has scope for entire program(global). Second block: the variable size has one scope Third block: variables i and temp has different scope

31 Scope rules and Block structure: In the above program there are five blocks Third :variables i and temp has different scope » Variable i is of type char but in global scope it is of type int » Until we come out of this 3 rd block (function f) the type of i will be char. When we come out of 3 rd block again variable i will be of type int. » Compiler is giving more priority to local variables. When we come out of the block the variable i of type char will be deleted and again variable i of type int will come in to picture.

32 Scope rules and Block structure: In the above program there are five blocks Third :variables i and temp has different scope – When processing this 3 rd block the symbol table will look like

33 Scope rules and Block structure: Variable i is saved twice with both types Variable i of type char is saved first, so when try to look up for variable i, it will return the char variable only (but not int variable) When we come out of the block, i (char) and temp (char) will be deleted from the symbol table

34 Scope rules and Block structure: In the above program there are five blocks Fourth block :variables j of type double will be added to the table and the symbol table looks like

35 Scope rules and Block structure: In the above program there are five blocks At the end of the function f block all the variables declared in it are deleted and the symbol table will be

36 Scope rules and Block structure: One more type of scope declaration is using different symbol tables for each block (as seen in the previous slides) and the practical implementation will look like

37 37 class Foo { int value; int test() { int b = 3; return value + b; } void setValue(int c) { value = c; { int d = c; c = c + d; value = c; } class Bar { int value; void setValue(int c) { value = c; } scope of value scope of b scope of c scope of value scope of d Symbol table example block1

38 38 class Foo { int value; int test() { int b = 3; return value + b; } void setValue(int c) { value = c; { int d = c; c = c + d; value = c; } class Bar { int value; void setValue(int c) { value = c; } Symbol table example SymbolKindTypeProperties valuefieldint… testmethod-> int setValuemethodint -> void (Foo) SymbolKindTypeProperties bvarint… (test) SymbolKindTypeProperties cvarint… (setValue) SymbolKindTypeProperties dvarint… (block1)

39 39 SymbolKindTypeProperties valuefieldint… testmethod-> int setValuemethodint -> void SymbolKindTypeProperties bvarint… SymbolKindTypeProperties cvarint… SymbolKindTypeProperties dvarint… (Foo) (test) … Symbol table example cont. (setValue) (block1)

40 40 Checking scope rules SymbolKindTypeProperties valuefieldint… testmethod-> int setValuemethodint -> void SymbolKindTypeProperties bvarint… SymbolKindTypeProperties cvarint… SymbolKindTypeProperties dvarint… (Foo) (test)(setValue) (block1) void setValue(int c) { value = c; { int d = c; c = c + d; value = c; } lookup(value)

41 41 SymbolKindTypeProperties valuefieldint… testmethod-> int setValuemethodint -> void SymbolKindTypeProperties bvarint… SymbolKindTypeProperties cvarint… SymbolKindTypeProperties dvarint… (Foo) (test)(setValue) (block1) void setValue(int c) { value = c; { int d = c; c = c + d; myValue = c; } lookup(myValue) Error ! undefined symbol Catching semantic errors

42 6.4 Data Types and Type Checking

43 Principal Task of Compiler Type inference The computation and maintenance of information on data types Type checking Type checking uses logical rules to reason about the behavior of a program at run time. Specifically, it ensures that the types of the operands match the type expected by an operator. For example, the && operator in Java expects its two operands to be booleans; the result is also of type boolean. The use of the information to ensure that each part of the program makes sense under the type rules of the language. These two tasks are related, performed together, and referred as type checking.

44 Data Type Data type information may be either static or dynamic, or a combination of two. Ex: In LISP type inference and type checking will be done during the execution(dynamic) Ex: In Pascal, C and Ada type information is primarily static, and is used as the principal mechanism for checking the correctness of the program before execution(static)


Download ppt "6. Semantic Analysis. Semantic Analysis Phase – Purpose: compute additional information needed for compilation that is beyond the capabilities of Context-"

Similar presentations


Ads by Google