CSE 6341 Programming Languages

Slides:



Advertisements
Similar presentations
1 Programming Languages (CS 550) Mini Language Interpreter Jeremy R. Johnson.
Advertisements

Semantics Static semantics Dynamic semantics attribute grammars
Attribute Grammars Prabhaker Mateti ACK: Assembled from many sources.
Intermediate Code Generation
Cs7120 (Prasad)L21-DCG1 Definite Clause Grammars
CS7100 (Prasad)L16-7AG1 Attribute Grammars Attribute Grammar is a Framework for specifying semantics and enables Modular specification.
Chapter 5 Syntax Directed Translation. Outline Syntax Directed Definitions Evaluation Orders of SDD’s Applications of Syntax Directed Translation Syntax.
Denotational Semantics Syntax-directed approach, generalization of attribute grammars: –Define context-free abstract syntax –Specify syntactic categories.
Programming Language Semantics Mooly SagivEran Yahav Schrirber 317Open space html://
Slide 1 Chapter 3 Attribute Grammars. Slide 2 Attribute Grammars Certain language structures cannot be described using EBNF. Attribute grammars are extensions.
Semantics with Applications Mooly Sagiv Schrirber html:// Textbooks:Winskel The.
CS241 PASCAL I - Control Structures1 PASCAL I - Control Structures Philip Fees CS241.
Winter 2003/4Pls – syntax – Catriel Beeri1 SYNTAX Syntax: form, structure The syntax of a pl: The set of its well-formed programs The rules that define.
CSE 6341 (755) Programming Languages
CSC 8310 Programming Languages Meeting 2 September 2/3, 2014.
CS784 (Prasad)L167AG1 Attribute Grammars Attribute Grammar is a Framework for specifying semantics and enables Modular specification.
Syntax & Semantic Introduction Organization of Language Description Abstract Syntax Formal Syntax The Way of Writing Grammars Formal Semantic.
1 Abstract Syntax Tree--motivation The parse tree –contains too much detail e.g. unnecessary terminals such as parentheses –depends heavily on the structure.
ISBN Chapter 3 Describing Semantics -Attribute Grammars -Dynamic Semantics.
CS 363 Comparative Programming Languages Semantics.
CSE 3341 Principles of Programming Languages Neelam Soundarajan Computer Sc. & Eng. Dreese Labs 579
Chapter 3 Part II Describing Syntax and Semantics.
Language Translation A programming language processor is any system that manipulates programs expressed in a PL A source program in some source language.
1 / 48 Formal a Language Theory and Describing Semantics Principles of Programming Languages 4.
1 A Simple Syntax-Directed Translator CS308 Compiler Theory.
Code Generation CPSC 388 Ellen Walker Hiram College.
CSE 3341/655; Part 3 35 This is all very wrong! What would the SW1/SW2 (RESOLVE) people say if they saw this? Problem: Lack of data abstraction; What would.
CSE 755, part4 Operational Semantics References: Kurtz (Ch. 8.4, 8.5, 8.6) Many ways to define o.s. of a language L: Define an interpreter for L Define.
Chapter 3 – Describing Syntax
Describing Syntax and Semantics
Describing Syntax and Semantics
Context-Sensitive Analysis
Information Science and Engineering
Introduction to Parsing
Introduction to Parsing (adapted from CS 164 at Berkeley)
Chapter 2 - Introduction to C Programming
Syntax Specification and Analysis
Core Core: Simple prog. language for which you will write an interpreter as your project. First define the Core grammar Next look at the details of how.
Principles of programming languages 4: Parameter passing, Scope rules
Revision Lecture
Context-Free Grammars
Ch. 4 – Semantic Analysis Errors can arise in syntax, static semantics, dynamic semantics Some PL features are impossible or infeasible to specify in grammar.
Compiler Lecture 1 CS510.
Compiler Construction (CS-636)
Chapter 2 - Introduction to C Programming
Parsing & Context-Free Grammars Hal Perkins Autumn 2011
Context-Free Grammars
Mini Language Interpreter Programming Languages (CS 550)
Context-Free Grammars
Prabhaker Mateti ACK: Assembled from many sources
Chapter 2 - Introduction to C Programming
Chapter 2 - Introduction to C Programming
CS1100 Computational Engineering
Chapter 6 Intermediate-Code Generation
Lecture 15 (Notes by P. N. Hilfinger and R. Bodik)
Chapter 2 - Introduction to C Programming
Representation, Syntax, Paradigms, Types
Lecture 4: Lexical Analysis & Chomsky Hierarchy
Syntax-Directed Translation
Compilers Principles, Techniques, & Tools Taught by Jing Zhang
Chapter 2 - Introduction to C Programming
SYNTAX DIRECTED DEFINITION
Axiomatic Semantics Will consider axiomatic semantics (A.S.) of IMP:
Context-Free Grammars
Chapter 2 - Introduction to C Programming
Compilers Principles, Techniques, & Tools Taught by Jing Zhang
Language semantics Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section
Context-Free Grammars
Language translation Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Sections
Presentation transcript:

CSE 6341 Programming Languages Neelam Soundarajan Computer Sc. & Eng. Dreese Labs 579 e-mail: neelam@cse

Outline Main Topic: Tentative Schedule: Ways to formally define syntax and semantics of PLs Plus … a bit about programming methodologies Tentative Schedule: Attribute grammars: 3 weeks Operational Semantics (including Lisp & its interpreter): 3.5 weeks Axiomatic Semantics: 3.5 weeks Denotational Semantics: 1 week Other topics: ?? Exams etc.: 0.5 week CSE 6341

References Unfortunately, no good books for the course. Mainly depend on slides, class discussions, your notes. Repeat: Slides are NOT class notes; slides are just bullet-points DO NOT miss classes. Some useful references: Formal specification of programming languages, F. Pagan Formal syntax and semantics of programming languages, Kurtz and Slonnegar Lisp 1.5 programmer’s manual, McCarthy and others Copies of all on reserve in the Sc./Eng. Library CSE 6341

Attribute Grammars (Ref.: Pagan (Ch. 2.3); Kurtz (Ch. 3)) Fact: Context-free conditions: specified using BNF Question: How do we specify context-sensitive (CS) conds? Answer: Using Attribute Grammars (AGs) An AG is: a BNF grammar + attributes + rules for evaluating attributes + conditions (to capture c.s. requirements) CSE 6341

Example L = { an bn cn | n >= 1 } <as> ::= a | a<as>1 Na(<as>)← 1 Na(<as>)← Na(<as>1)+1 <bs> ::= b | b<bs>1 Nb(<bs>)← 1 Nb(<bs>)← Nb(<bs>1)+1 <cs> ::= c | c<cs>1 Nc(<cs>)← 1 Nc(<cs>)← Nc(<cs>1)+1 <ls> ::= <as><bs><cs> Cond: Na(<as) = Nb(<bs>) = Nc(<cs>) Na: Synthesized attribute of <as> Nb: Synthesized attribute of <bs> Nc: Synthesized attribute of <cs> No inherited attributes in this grammar. CSE 6341

Some Comments Consider how the grammar works with a parse tree, allowing, say, "aabbcc", and disallowing "aabcc" Attributes are NOT program variables; can't have: Na(<as>) ← Na(<as>) + 1 In rules/conditions, can only refer to attributes of non- terminal on the left and the non-terminals in the current alternative. Can't look at "grand children" etc. Could have used N (instead of Na, Nb, Nc) as the name of all three attributes. CSE 6341

Example (revisited) L = { an bn cn | n >= 1 } <ls> ::= <as><bs><cs> ExpNb(<bs>) ← Na(<as>) ExpNc(<cs>) ← Na(<as>) <as> ::= a | a<as>1 Na(<as>)← 1 Na(<as>)← Na(<as>1)+1 <bs> ::= b | b<bs>1 Cond: ExpNb(<bs>) =1 ExpNb(<bs>1) ← ExpNb(<bs>) −1 <cs> ::= c | c<cs>1 Cond: ExpNc(<cs>) =1 ExpNc(<cs>1) ← ExpNc(<cs>) −1 Na: Synthesized attribute of <as> ExpNb: Inherited attribute of <bs> ExpNc: Inherited attribute of <cs> Consider all strings over {a,b,c} (i.e., a's, b's, c's may be in any order) and require: no. of a's = no. of b's = no. of c's (using synh. & synth+inh. attr) CSE 6341

Some Comments An AG is a BNF grammar plus a set of attributes, some synth., others inh. Each attribute is associated with a specific non-terminal. If S is a synth. attrib. of <N>, then for each alternative in <N>'s production, must have an eval. rule that will be used to compute S(<N>) whenever that alternative is used. If I is an inh. attrib. of <N>, then for each occurrence of <N> on the right side of any production, must have eval. rule that will be used to computer I(<N>) if that alternative is used. Conditions are associated with individual alternatives of individual productions. If any condition in a tree evaluates to false, the tree collapses CSE 6341

Context-free condns. using AGs CF conditions can also be expressed using AGs. L = { an bn | n >= 1 } <ls> ::= <as><bs> Cond: Na(<as>) = Nb(<bs>) AGs can be used to capture precedence, i.e., specify how a string is to be parsed: Consider all strings over {a, b}. Given "abab", want to ensure it is parsed as a(b(a(b))), not as (ab)(ab) etc.: <str> ::= a | b N(<str>)← 1 N(<str>)← 1 | <str>1<str>2 N(<str>) ← N(<str>1) + N(<str>2) Cond: (N(<str>1) = 1) CSE 6341

Context-sens. condns. in PLs Main condition: Id's that are used must have been declared <prog> ::= <block> <block> ::= begin <decl seq> <stmt seq> end; How to ensure that in <stmt seq> we only use objects declared in <decl seq>? Using synthesized attributes: Cond: UsedIds(<stmt seq>)  DeclIds(<decl seq>) Using inherited attributes: AllowedIds(<stmt seq>) ← DeclIds(<decl seq>) CSE 6341

CS conditions in PLs (contd.) Problem: Nested blocks (what are they?) Solution: Use a sequence of sets, each containing Ids declared in a (surrounding) block <block> ::= begin <decl seq> <stmt seq> end; Nest(<stmt seq>) ← append(Nest(<block>), Decs(<decl seq>)) <stmt seq> ::= <stmt> Nest(<stmt>) ← Nest(<stmt seq>) | <stmt><stmt seq>1 Nest(<stmt>), Nest(<stmt seq>1) ← Nest(<stmt seq>) <program> ::= <block> Nest(<block>) ← <> CSE 6341

CS conditions in PLs (contd.) Problem: Different types of Ids Solution: An element of Decs() is of the form: ("xy", int), or ("ab", bool), or ("PQ", proc) (For procedures, also need info about no./types of pars) Where do we check (that the CS conds. are satisfied)? <assign> ::= <id> := <int exp>; Cond: lastType(Name(<id>, Nest(<assign>) = int <id> := <bool exp>; Cond: lastType(Name(<id>, Nest(<assign>) = bool CSE 6341

CS conditions in PLs (contd.) <proc call> ::= call <id>(); Cond: lastType(Name(<id>), Nest(<proc call>)) = proc  parTypes(Name(<id>), Nest(<proc call>)) = <> | call <id>(<arg list); Cond: lastType(Name(<id>), Nest(<proc call>)) = proc  parTypes(Name(<id>), Nest(<proc call>)) = ... Question: What about double declarations? <ds> ::= <decl> Decs(<ds>) ← Decs(<decl>); Nest(<decl>)←Nest(<ds>) | <decl> <ds>1 Decs(<ds>) ← Decs(<decl>)  Decs(<ds>1) Nest(<decl>), Nest (<ds>1) ← Nest(<ds>) Cond: Decs(<decl>)  Decs(<ds>1) =  // Not quite? CSE 6341

Note: Maybe better to look at e. g. in pp **Note: Maybe better to look at e.g. in pp. 15/16 before grammar rules below** Questions: How do elements get into Decs()? How do procs access surr. block/call other procs? (Ans: Need to pass Nest also to the <decl>s.) <block> ::= begin <decl seq> <stmt seq> end; Nest(<stmt seq>) ← append(Nest(<block>), Decs(<decl seq>)) Nest(<decl seq>) ← append(Nest(<block>), Decs(<decl seq>)) <decl> ::= int <id>; Decs(<decl>) ← {(Name(<id>), int)} | bool <id>; Decs(<decl>) ← {(Name(<id>), bool)} | proc <id>() <block> Decs(<decl>) ← {(Name(<id>), proc, <>)} Nest(<block>) ← Nest(<decl>) // need to change? | proc <id>(<par list>) <block> Decs(<decl>) ← {(Name(<id>), proc, Partypes(<par list>))} Nest(<block>) ← append(Nest(<decl>), Decs(<par list>)) CSE 6341

<prog> <block> <ds> <ss> <d> <ds> int X, Y <d> proc P(int U, bool Y) <block> <ds> <d> proc Q() <block> <ss> <ds> <d> proc X() <block> <stmt> <block> <ds> <ss> <d> proc X() <block> CSE 6341

<prog> <block> <ds> <ss> <d> <ds> N1 <ds> <ss> D2 N2 D3 N3 <d> <ds> D4 N4 D5 N5 int X, Y <d> proc P(int U, bool Y) <block> <ds> D7 N7 D6 N6 <d> D17 D18 D8 N8 proc Q() <block> <ss> D18 N18 <ds> D10 N10 D9 N9 <d> proc X() <block> <stmt> D10 N10 <block> D12 N12 D11 N11 <ds> <ss> D14 N14 <d> proc X() <block> D13 N13 D15 N15 D16 N16 CSE 6341

Translational Semantics AGs also used to specify translations (code generation) (e.g.: YACC) (Ref: Pagan (ch. 3.2); Kurtz (ch. 7)) Basic idea: <stmt> ::= <stmt>1; <stmt>2 Code(<stmt>)← append(Code(<stmt>1), Code(<stmt>2)) but the details are more complex ... E.g.: How to ensure the same label is not used in Code(<stmt>1) and Code(<stmt>2) ? A simple imperative language (we will call it IMP; taken from Pagan): <prog> ::= <stmt> <stmt> ::= skip; | <assign> | <stmt>1;<stmt>2 | if <be> then<stmt>1 else <stmt>2 | while <be> do <stmt>1 <assign> ::= <id> := <ae>; <ae> ::= <id> | <int> | <ae>1+<ae>2 | <ae>1  <ae>2 | <ae>1 * <ae>2 <be> ::= true | false | <ae>1=<ae>2 | <ae>1 < <ae>2 | <be> | <be>1  <be>2 | <be>1  <be>2 CSE 6341

Translational Semantics (contd.) Key attributes: Code: a synth. attribute of <stmt>, <ae>, <be>: The seq. of assembly instructions corresponding to a particular <stmt>, <ae>, <be> Labin (inh.), Labout (synth.): keep track of next available label Temp (inh.): keeps track of next available memory loc. for temporary use <prog> ::= <stmt> Code(<prog>) ← Code(<stmt>) Labin(<stmt>) ← 1 <stmt> ::= <stmt>1;<stmt>2 Code(<stmt>) ← append(Code(<stmt>1), Code(<stmt>2)) Labin(<stmt>1) ← Labin(<stmt>) Labin(<stmt>2) ← Labout(<stmt>1) Labout(<stmt>) ← Labout(<stmt>2) CSE 6341

Translational Semantics (contd.) <stmt> ::= <assign> Code(<stmt>) ← Code(<assign>) Labout(<stmt>) ← Labin(<stmt>) // why? | if <be> then <stmt>1 else <stmt>2 Labin(<stmt>1) ← Labin(<stmt>) + 2 // why? Labin(<stmt>2) ← Labout(<stmt>1) Labout(<stmt>) ← Labout(<stmt>2) Code(<stmt>) ← append( Code(<be>), ("BZ", Labin(<stmt>)), // slight problem Code(<stmt>1), ("BR", label(Labin(<stmt>)+1)), (label(Labin(<stmt>)) "No-Op"), Code(<stmt>2), (label(Labin(<stmt>)+1) "No-Op") ) | while <be> do <stmt>1 Labin(<stmt>1) ← ... Labout(<stmt>) ← ... Code(<stmt>) ← ... BZ: "branch on zero"; BR: "unconditional branch"; "No-Op": "continue". CSE 6341

Translational Semantics (contd.) <assign> ::= <id> := <ae>; Code(<assign>) ← append(Code(<ae>), ("STO", Name(<id>)) Temp(<ae>) ← 1 <ae> ::= <int> Code(<ae>) ← <("LOAD" Value(<int>))> | <id> Code(<ae>) ← <("LOAD" Name(<id>))> | <ae>1+<ae>2 Code(<ae>) ← append( Code(<ae>1), ("STO" temp(Temp(<ae>)), Code(<ae>2), ("ADD" temp(Temp(<ae>))) ) Temp(<ae>1) ←Temp(<ae>) Temp(<ae>2) ←Temp(<ae>) + 1 // why? CSE 6341

Static Scope (Algol, Pascal, C, C++,...) Entities accessible in a procedure: Entities declared in that procedure + Entities declared in the “surrounding” procedure (less those with name conflicts) + Entities declared in procedure surrounding the surrounding procedure + ... Visualize: Each procedure is a box whose sides are one-way mirrors: you can look out of the box, but you can’t look into a box Some languages are not quite static scope but are close. CSE 6341

Example program A, B, C: integer; Q: procedure // no parameters begin B := B+2; C := C+2; print A, B, C; end (Q); R: procedure A: integer; begin A := 3; C := 2; call Q; B := A+C; print A, B, C; end (R); S: procedure A, C: integer; Q: procedure // nested in S C: integer; begin A := A+1; C := B+1; print A, B, C; end (S.Q); begin // body of S B := 3; C := 1; A := 4; print A, B, C; call R; print A, B, C; end (S); begin // main body A := 1; B := 1; C := 1; call R; print A, B, C; call S; print A, B, C; end (main); A C Q R S CSE 6341