Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chapter 4 Action Routines.

Similar presentations


Presentation on theme: "Chapter 4 Action Routines."— Presentation transcript:

1 Chapter 4 Action Routines

2 Syntax and Semantics In general: In programming languages:
Syntax – form Semantics – meaning In programming languages: Syntax – part of the language definition that can be described via a context-free grammar Semantics – part of language definition that can’t.

3 Non-Syntax Items Can’t be enforced by a context-free grammar:
Variables must be declared before use Variables must be assigned before use Type compatibility in expressions Number and type of arguments must match the number and type of formal parameters Procedure must contain a return statement for each execution path

4 Semantics Recall, semantics can be broken into:
Static semantics – can be enforced by the compiler at compile time Dynamic semantics – enforced at run-time, probably via code generated at compile time by the compiler.

5 Evaluating Attribute Grammars
Attribute grammar variables can be characterized as: Intrinsic – look-up value Synthesized – Variables on the left side of a production get attribute values calculated from values on the right side of the production. In other words, attribute values come from values lower in the parse tree. Inherited – Variables on the right side of a production get attribute values from items on the left side of the production or items to the left of the variable. In other words, values come from parents or siblings on the right in the parse tree.

6 Synthesized Attributes
Simple attribute grammar for constant expressions using standard arithmetic operations Figure 4.1, page 181

7 Evaluating Attributes

8 Synthesized & Inherited Attributes
Attribute grammar for constant expressions based on LL(1) context-free grammar. Several productions have two semantic rules Figure 4.3, page 186

9 Evaluating Attributes - Example

10 Attribute Grammars Semantic analysis and code generation can be described in terms of annotation, or “decoration” of a parse or syntax tree Attribute grammars provide a formal framework for decorating such a tree

11 Example Context-Free Grammar
E → E + T E → E – T E → T T → T * F T → T / F T → F F → - F Says nothing about what the program means

12 Example Attribute Grammar
E → E + T E1.val = E2.val + T.val E → E – T E1.val = E2.val - T.val E → T E.val = T.val T → T * F T1.val = T2.val * F.val T → T / F T1.val = T2.val / F.val T → F T.val = F.val F → - F F1.val = - F2.val

13 Assertions Some languages allow programmers to write logical assertions about values of program data Example: assert denominator != 0 C allows via library routine assert Ada and Java have built-in language support for assertions Euclid and Eiffel include explicit support for invariants, preconditions and post-conditions

14 Action Routines Action routine – a semantic function that a grammar writer can associate with a grammar for the compiler to execute at particular points during parsing Action routines are more flexible than attribute grammars.

15 Action Routines Action routines – routines attached to a grammar which is executed by the compiler as it parses code Often used in production compilers Can be used to build parse trees

16 Example for LL Parsing LL parsing – action routines can appear anywhere within a right-had side. Pointer to the action routine is pushed onto the stack and is executed when it is at the top of the stack. Thus: Action routine at the beginning is executed when the parser predicts the production Routine embedded in the middle of the right-hand side is executed when the parser “matches” the symbol to its left

17 Action Routine Example
Consider the grammar: E → T TT TT → + T TT | T TT | ε T → F FT FT → * F FT | / F FT | ε F → - F F → ( E ) F → const Figure 4.9 in text, page 195

18 Action Routine Example
Action routines added: E → T {TT.st:=T.ptr} TT {E.ptr:=TT.ptr} TT1 → T {TT2.st:=make_bin_op(“+”,TT1.st,T.ptr)} TT2 {TT1.ptr:=TT2.ptr} TT1 → T {TT2.st:=make_bin_op(“-”,TT1.st,T.ptr)} TT2 {TT1.ptr:=TT2.ptr} TT → ε {TT.ptr:=TT.st} T → F {FT.st:=F.ptr} FT {T.ptr:=FT.ptr}

19 Action Routine Example - continued
FT1 → F {FT2.st:=make_bin_op(“x”,FT1.st,F.ptr)} FT2 {FT1.ptr:=FT2.ptr} FT1 → F {FT2.st:=make_bin_op(“/”,FT1.st,F.ptr)} FT2 {FT1.ptr:=FT2.ptr} FT → ε {FT.ptr:=FT.st} F1 → F2 {F1.ptr:=make_un_op(“+/-”,FT2.ptr)} F → (E) {F.ptr:=E.ptr} F → const {F.ptr:=make_leaf(const.ptr)}

20 Build Tree Use the previous grammar with action routines to build a tree for the expression: 2 * 3 + 5

21 Build Tree Stack: F F → const {F.ptr:=make_leaf(const.ptr)} FT T TT E

22 Build Tree Stack: FT1→ * F {FT2.st:= make_bin_op(“x”,FT1.st, F.ptr)} FT2 {FT1.ptr:= FT2.ptr} * F FT TT

23 Simplified Action Routine Example
Demonstrating action routines using a more simple (LR) grammar. E → E + T E → E – T E → T T → T * F T → T / F T → F F → - F F → (E) F → const

24 Simplified Action Routine Example
More simplified example: E → E + T E1.ptr:= make_bin_op(“+”, E2.ptr, T.ptr) E → E - T E1.ptr:= make_bin_op(“-”, E2.ptr, T.ptr) E → T E.ptr:= T.ptr T → T * F T1.ptr:= make_bin_op(“x”, T2.ptr, F.ptr) T → T / F T1.ptr:= make_bin_op(“/”, T2.ptr, F.ptr) T → F T.ptr:= F.ptr F → - F F1.ptr:= make_un_op(“+/-”, F2.ptr) (+/- - indicates a change of sign, similar to on calculators) F → (E) F.ptr:=E.ptr F → const F.ptr:=make_leaf(const.val)


Download ppt "Chapter 4 Action Routines."

Similar presentations


Ads by Google