meeting -*- Outline -*- * inductively sets of data (EOPL2e 1.1) The big picture: languages contain infinite number of sentences, so must be inductively specified grammars a way of specifying inductive sets interpreters are recursive because follow grammar For us, inductive specs are more important than induction as a proof technique ** inductive specification useful for saying what the values are in an ADT a programming language ------------------------------------------ INDUCTIVE SPECIFICATION (1.1) EXAMPLES The set N of natural numbers is the smallest set such that: 1. 0 is in N 2. if i in N, then i+1 is in N Let Digit = {0,1,2,3,4,5,6,7,8,9} The set Numeral of numerals is the smallest set such that 1. 2. ------------------------------------------ Q: Why isn't N = {..., -2, -1, 0, 1, 2, ...}? not the smallest ... if x is in Digit, then x in Numeral ... if x is in Digit, and n in Numeral, then x:n is in Numeral ------------------------------------------ FOR YOU TO DO Let symbol be the set of symbols. Specify the set (list-of symbol), i.e., the set of lists of symbols. ------------------------------------------ ... The set (list-of symbol) of lists of symbols is the smallest set such that 1. () is in (list-of symbol) 2. if s is a symbol, and l is a (list-of symbol), then the pair (s . l) is a (list-of symbol). (cons s l) is the right idea, but mixes levels (expressions and values) as would '() instead of (). Another way: if (s1 ...) is a (list-of symbol) then (s s1 ...) is a (list-of symbol) The following isn't inductive: if s1, ..., sn are symbols, for n>=0, then (s1 ... sn) is a (list-of symbol) ** use of grammars in programming languages ------------------------------------------ THE USE OF GRAMMARS IN PROGRAMMING LANGUAGES In definition: !--------------------------------------! ! all strings over alphabet ! ! !---------------------------------! ! ! ! regular grammar ! ! ! ! !-----------------------------! ! ! ! ! ! context-free grammar ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !-----------------------------! ! ! ! !---------------------------------! ! !--------------------------------------! In implementation (parsing): input tokens ========> lexer ========> parser ! ! trees v code gen ! ! code v object module ------------------------------------------ Q: Why do programming languages typically use 2 layers of grammar? it allows more abstraction Q: How could we avoid the repition in inductive specifictions? use a special notation, grammars... ** Backus-Naur Form (BNF) (1.1.2) ------------------------------------------ BACKUS-NAUR FORM (BNF) (1.1.2) ::= ( ) ::= ( . ) Notation, terms: ::= syntactic category, non-terminal terminal rule, production ALTERNATIVE SHORTHAND ::= ( ) | ( . ) ------------------------------------------ ------------------------------------------ FOR YOU TO DO Given and , write a grammar for that includes the following examples: 3 x (5 + 4) (x + ((7 * 8) / y)) (9 - z) ------------------------------------------ ::= | | ( ) ::= + | - | * | / ------------------------------------------ KLEENE STAR AND PLUS ::= ( {}* ) ::= ( {}+ ) ------------------------------------------ explain the notation, terms, but don't write it all out, as it's in the book implicit grammar rules: {}* ::= | {}* {}+ ::= | {}+ ------------------------------------------ KLEENE STAR AND PLUS USED IN REGULAR GRAMMARS ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 ::= {}+ ::= a | ... | z | A | ... | Z ::= - | _ | + | * | ? | / | ! | ::= | ::= {}* {}* ------------------------------------------ go over this quickly ------------------------------------------ DERIVATIONS Replace one non-terminal using a rule at each step Grammar: ::= ( ) | ( . ) Derivation of (fly): ==> Grammar: ::= ( {}* ) Derivation of (fly): ==> ------------------------------------------ ... ( . ) ==> ( fly . ) ==> ( fly . () ) = ( fly ) ; because of the equivalence of ( fly . () ) and (fly) The following is a bit hard to grasp, as it relies on understanding Kleene Star notation. The implicit rules used are: {}* ==> {}* ==> {}* ... ( {}* ) ==> ( {}* ) ==> ( fly {}* ) ==> ( fly ) Q: how does this help in defining a programming language? ------------------------------------------ FOR YOU TO DO Consider the following grammar: ::= | | ( lambda ( {}+ ) ) | ( {}+ ) If the following are s, then give a derivation, else show why there is no derivation. a. x b. ((lambda (x) x) 3) c. f(3, 4) ------------------------------------------ The implicit rule is: {}+ ==> {}+ ==> {}+ Summary: BNF is a good way to write an inductive specification, especially for a language. ** Using BNF to specify data (2.1.3) ------------------------------------------ USING BNF TO SPECIFY DATA (2.1.3) ::= ( {}* ) ::= ( ) | ( . ) ::= ( ``` . ) ::= ( . ) ::= ( . ( {}* )) ::= () | ::= ( . ) ::= ------------------------------------------ different ways of specifying the same data are possible, as with the list-of-symbol example the grammar can describe several data structures, as in the closure example ... (exp-stmt ) | (set! ) ::= (var-exp ) | (num-exp ) | (begin {}* ) Q: What would be the base case for a procedure that took a as an argument? Q: What would the recursive case be? Q: What are the cases for a ? Q: What would the recursive case be? Q: What are the cases for ? ? ------------------------------------------ SPECIFYING SCHEME DATA ::= | | | | | | | ::= ( {}* ) ::= ( . ) ::= #( {}* ) ::= ::= ------------------------------------------ Q: How would you specify without using the Kleene star? ------------------------------------------ CONTEXT-FREE vs. CONTEXT-SENSITIVE ::= () | ( ::= ------------------------------------------ ... ) Q: What would make this into a binary search tree? Q: Is there any way to specify this in a context-free grammar? terms: context-free, context-sensitive ** induction (2.1.4) (omit) can use induction to prove properties of inductively specified types. example: every bin-tree has an odd numbr of nodes. where a node is either () or ( ) ```