1
Quiz 4
2
Midterm 2 ADT, Second Chance
type ‘a option =
| None
| Some of ‘a
3
Programming Languages and Compilers (CS 421)
Based heavily on slides by Elsa Gunter, which were based in part on slides by Mattox Beckman, as updated by Vikram Adve and Gul Agha
Objectives for Today
*
4
Objectives for Today
*
5
Objectives for Today
*
6
7
Questions from last week?
8
Recap
Example : using generated file
# #use "test.ml";;
…
val main : Lexing.lexbuf -> result = <fun>
val __ocaml_lex_main_rec :
Lexing.lexbuf -> int -> result = <fun>
hi there 234 5.2
- : result = String "hi”
*
9
Recap
Example : using generated file
# #use "test.ml";;
…
val main : Lexing.lexbuf -> result = <fun>
val __ocaml_lex_main_rec :
Lexing.lexbuf -> int -> result = <fun>
hi there 234 5.2
- : result = String "hi”
*
10
What happened to the rest?
Recap
Example : using generated file
# let b = Lexing.from_channel stdin;;
# main b;;
hi 673 there
- : result = String "hi"
# main b;;
- : result = Int 673
# main b;;
- : result = String "there"
*
11
Recall the hidden argument of type lexbuf
Recap
Example : using generated file
# let b = Lexing.from_channel stdin;;
# main b;;
hi 673 there
- : result = String "hi"
# main b;;
- : result = Int 673
# main b;;
- : result = String "there"
*
12
Recall the hidden argument of type lexbuf
Recap
Example : using generated file
# let b = Lexing.from_channel stdin;;
# main b;;
hi 673 there
- : result = String "hi"
# main b;;
- : result = Int 673
# main b;;
- : result = String "there"
*
13
Recall the hidden argument of type lexbuf
Recap
14
Fancy Lexing
Problem
*
15
Fancy Lexing
Problem
*
16
Fancy Lexing
Problem
*
17
Fancy Lexing
Example: Old Version
rule main = parse
| (digits)'.'digits as f
{ Float (float_of_string f) }
| digits as n
{ Int (int_of_string n) }
| letters as s
{ String s }
| _ { main lexbuf }
*
18
Fancy Lexing
Example: WIP New Version
rule main = parse
| (digits)'.'digits as f
{ Float (float_of_string f) :: main lexbuf }
| digits as n
{ Int (int_of_string n) :: main lexbuf }
| letters as s
{ String s :: main lexbuf }
| _ { main lexbuf }
*
19
Fancy Lexing
Example: New Version
rule main = parse
| (digits)'.'digits as f
{ Float (float_of_string f) :: main lexbuf }
| digits as n
{ Int (int_of_string n) :: main lexbuf }
| letters as s
{ String s :: main lexbuf }
| eof { [] }
| _ { main lexbuf }
*
20
Fancy Lexing
Example Results
hi there 234 5.2
- : result list = � [String "hi"; String "there"; Int 234; Float 5.2]
Used Ctrl-d to send the end-of-file signal
*
21
Fancy Lexing
22
Questions so far?
Fancy Lexing
Dealing with Comments (No Nesting)
let open_comment = "(*"
let close_comment = "*)"
rule main = parse
… (* same as last time *)
| open_comment { comment lexbuf }
| eof { [] }
| _ { main lexbuf }
and comment = parse
| close_comment { main lexbuf }
| _ { comment lexbuf }
*
23
Fancy Lexing
Dealing with Comments (No Nesting)
let open_comment = "(*"
let close_comment = "*)"
rule main = parse
… (* same as last time *)
| open_comment { comment lexbuf }
| eof { [] }
| _ { main lexbuf }
and comment = parse
| close_comment { main lexbuf }
| _ { comment lexbuf }
*
24
Fancy Lexing
Dealing with Comments (No Nesting)
let open_comment = "(*"
let close_comment = "*)"
rule main = parse
… (* same as last time *)
| open_comment { comment lexbuf }
| eof { [] }
| _ { main lexbuf }
and comment = parse
| close_comment { main lexbuf }
| _ { comment lexbuf }
*
25
Fancy Lexing
Dealing with Comments (No Nesting)
let open_comment = "(*"
let close_comment = "*)"
rule main = parse
… (* same as last time *)
| open_comment { comment lexbuf }
| eof { [] }
| _ { main lexbuf }
and comment = parse
| close_comment { main lexbuf }
| _ { comment lexbuf }
*
26
Fancy Lexing
Dealing with Comments (No Nesting)
let open_comment = "(*"
let close_comment = "*)"
rule main = parse
… (* same as last time *)
| open_comment { comment lexbuf }
| eof { [] }
| _ { main lexbuf }
and comment = parse
| close_comment { main lexbuf }
| _ { comment lexbuf }
*
27
Fancy Lexing
28
Questions so far?
Fancy Lexing
Dealing with Nested Comments
rule main = parse
…
| open_comment { comment 1 lexbuf}
| eof { [] }
| _ { main lexbuf }
and comment depth = parse
| open_comment { comment (depth+1) lexbuf }
| close_comment { if depth = 1 then main lexbuf
else comment (depth - 1) lexbuf }
| _ { comment depth lexbuf }
*
29
Fancy Lexing
Dealing with Nested Comments
rule main = parse
…
| open_comment { comment 1 lexbuf}
| eof { [] }
| _ { main lexbuf }
and comment depth = parse
| open_comment { comment (depth + 1) lexbuf }
| close_comment { if depth = 1 then main lexbuf
else comment (depth - 1) lexbuf }
| _ { comment depth lexbuf }
*
30
Fancy Lexing
Dealing with Nested Comments
rule main = parse
…
| open_comment { comment 1 lexbuf}
| eof { [] }
| _ { main lexbuf }
and comment depth = parse
| open_comment { comment (depth + 1) lexbuf }
| close_comment { if depth = 1 then main lexbuf
else comment (depth - 1) lexbuf }
| _ { comment depth lexbuf }
*
31
Fancy Lexing
Dealing with Nested Comments
rule main = parse
…
| open_comment { comment 1 lexbuf}
| eof { [] }
| _ { main lexbuf }
and comment depth = parse
| open_comment { comment (depth + 1) lexbuf }
| close_comment { if depth = 1 then main lexbuf
else comment (depth - 1) lexbuf }
| _ { comment depth lexbuf }
*
32
Fancy Lexing
Dealing with Nested Comments
rule main = parse
…
| open_comment { comment 1 lexbuf}
| eof { [] }
| _ { main lexbuf }
and comment depth = parse
| open_comment { comment (depth + 1) lexbuf }
| close_comment { if depth = 1 then main lexbuf
else comment (depth - 1) lexbuf }
| _ { comment depth lexbuf }
*
33
Fancy Lexing
Dealing with Nested Comments
rule main = parse
…
| open_comment { comment 1 lexbuf}
| eof { [] }
| _ { main lexbuf }
and comment depth = parse
| open_comment { comment (depth + 1) lexbuf }
| close_comment { if depth = 1 then main lexbuf
else comment (depth - 1) lexbuf }
| _ { comment depth lexbuf }
*
34
Fancy Lexing
Dealing with Nested Comments
rule main = parse
…
| open_comment { comment 1 lexbuf}
| eof { [] }
| _ { main lexbuf }
and comment depth = parse
| open_comment { comment (depth + 1) lexbuf }
| close_comment { if depth = 1 then main lexbuf
else comment (depth - 1) lexbuf }
| _ { comment depth lexbuf }
*
35
Fancy Lexing
Dealing with Nested Comments
rule main = parse
…
| open_comment { comment 1 lexbuf}
| eof { [] }
| _ { main lexbuf }
and comment depth = parse
| open_comment { comment (depth+1) lexbuf }
| close_comment { if depth = 1 then main lexbuf
else comment (depth - 1) lexbuf }
| _ { comment depth lexbuf }
*
36
Fancy Lexing
37
Note: No Longer Regular!
Fancy Lexing
38
Often easier to defer non-regular
things to the parser generator.
Fancy Lexing
Problem
*
39
Fancy Lexing
40
Questions so far?
41
Parsing
Lexing and Parsing
Source Program
Tokens
Abstract Syntax
Semantic Analysis
Symbol Table
Evaluation/
Translation
Result/IR
Lexer
Parser
Parsing
42
Lexing and Parsing
Source Program
Tokens
Abstract Syntax
Semantic Analysis
Symbol Table
Evaluation/
Translation
Result/IR
Lexer
Parser
To parse our source program and get abstract syntax, we need a grammar defined in terms of the kinds of tokens we get out of our lexer.
Parsing
43
Lexing and Parsing
Source Program
Tokens
Abstract Syntax
Semantic Analysis
Symbol Table
Evaluation/
Translation
Result/IR
Lexer
Parser
To parse our source program and get abstract syntax, we need a grammar defined in terms of the kinds of tokens we get out of our lexer.
The output, an abstract syntax tree, will track not just categories, but also structure.
Parsing
44
Lexing and Parsing
Binary Operator +
The output, an abstract syntax tree, will track not just categories, but also structure.
*
45
Constant 1
Constant 2
Syntax
Parsing
Lexing and Parsing
Source Program
Tokens
Abstract Syntax
Semantic Analysis
Symbol Table
Evaluation/
Translation
Result/IR
Lexer
Parser
To parse our source program and get abstract syntax, we need a grammar defined in terms of the kinds of tokens we get out of our lexer.
The output, an abstract syntax tree, will track not just categories, but also structure.
Parsing
46
Sample Grammar
<Sum> ::= 0
<Sum> ::= 1
<Sum> ::= <Sum> + <Sum>
<Sum> ::= (<Sum>)
*
47
Parsing
Sample Grammar
<Sum> ::= 0
<Sum> ::= 1
<Sum> ::= <Sum> + <Sum>
<Sum> ::= (<Sum>)
*
48
Parsing
49
Context-Free Grammars
BNF Grammars
*
50
Context-Free Grammars
BNF Grammars
*
51
Context-Free Grammars
BNF Grammars
*
52
Context-Free Grammars
BNF Grammars
*
53
Context-Free Grammars
Sample BNF Grammar
<Sum> ::= 0
<Sum> ::= 1
<Sum> ::= <Sum> + <Sum>
<Sum> ::= (<Sum>)
*
54
Context-Free Grammars
Sample BNF Grammar
<Sum> ::= 0
<Sum> ::= 1
<Sum> ::= <Sum> + <Sum>
<Sum> ::= (<Sum>)
Can be abbreviated as
<Sum> ::= 0 | 1 | <Sum> + <Sum> | (<Sum>)
*
55
Context-Free Grammars
56
Questions so far?
Context-Free Grammars
BNF Semantics
*
57
Context-Free Grammars
BNF Semantics
*
58
Context-Free Grammars
BNF Deriviations
X ::= yZw and Z ::= v
we may replace Z by v to say
X => yZw => yvw
*
59
Context-Free Grammars
BNF Deriviations
X ::= yZw and Z ::= v
we may replace Z by v to say
X => yZw => yvw
*
60
Context-Free Grammars
BNF Derivations
Start with the start symbol:
<Sum> =>
*
61
Context-Free Grammars
BNF Derivations
Pick a non-terminal:
<Sum> =>
*
62
Context-Free Grammars
BNF Derivations
Pick a rule and substitute:
<Sum> => <Sum> + <Sum >
*
63
Context-Free Grammars
BNF Derivations
Pick a non-terminal:
<Sum> => <Sum> + <Sum >
*
64
Context-Free Grammars
BNF Derivations
Pick a rule and substitute:
<Sum> => <Sum> + <Sum >
=> ( <Sum> ) + <Sum>
*
65
Context-Free Grammars
BNF Derivations
Pick a non-terminal:
<Sum> => <Sum> + <Sum >
=> ( <Sum> ) + <Sum>
*
66
Context-Free Grammars
BNF Derivations
Pick a rule and substitute:
<Sum> => <Sum> + <Sum >
=> ( <Sum> ) + <Sum>
=> ( <Sum> + <Sum> ) + <Sum>
*
67
Context-Free Grammars
BNF Derivations
Pick a non-terminal:
<Sum> => <Sum> + <Sum >
=> ( <Sum> ) + <Sum>
=> ( <Sum> + <Sum> ) + <Sum>
*
68
Context-Free Grammars
BNF Derivations
Pick a rule and substitute:
<Sum> => <Sum> + <Sum >
=> ( <Sum> ) + <Sum>
=> ( <Sum> + <Sum> ) + <Sum>
=> ( <Sum> + 1 ) + <Sum>
*
69
Context-Free Grammars
BNF Derivations
Pick a non-terminal:
<Sum> => <Sum> + <Sum >
=> ( <Sum> ) + <Sum>
=> ( <Sum> + <Sum> ) + <Sum>
=> ( <Sum> + 1 ) + <Sum>
*
70
Context-Free Grammars
BNF Derivations
Pick a rule and substitute:
<Sum> => <Sum> + <Sum >
=> ( <Sum> ) + <Sum>
=> ( <Sum> + <Sum> ) + <Sum>
=> ( <Sum> + 1 ) + <Sum>
=> ( <Sum> + 1 ) + 0
*
71
Context-Free Grammars
BNF Derivations
Pick a non-terminal:
<Sum> => <Sum> + <Sum >
=> ( <Sum> ) + <Sum>
=> ( <Sum> + <Sum> ) + <Sum>
=> ( <Sum> + 1 ) + <Sum>
=> ( <Sum> + 1 ) + 0
*
72
Context-Free Grammars
BNF Derivations
Pick a rule and substitute
<Sum> => <Sum> + <Sum >
=> ( <Sum> ) + <Sum>
=> ( <Sum> + <Sum> ) + <Sum>
=> ( <Sum> + 1 ) + <Sum>
=> ( <Sum> + 1 ) 0
=> ( 0 + 1 ) + 0
*
73
Context-Free Grammars
BNF Derivations
( 0 + 1 ) + 0 is generated by the grammar.
<Sum> => <Sum> + <Sum >
=> ( <Sum> ) + <Sum>
=> ( <Sum> + <Sum> ) + <Sum>
=> ( <Sum> + 1 ) + <Sum>
=> ( <Sum> + 1 ) + 0
=> ( 0 + 1 ) + 0
*
74
Context-Free Grammars
75
Questions so far?
Context-Free Grammars
Extended BNF Grammars
*
76
Context-Free Grammars
Extended BNF Grammars
*
77
Context-Free Grammars
Extended BNF Grammars
*
78
Context-Free Grammars
79
Questions?
80
Next Class: From Tokens to ASTs
Next Class
81