CS 314 Principles of Programming Languages Lecture 9 Zheng Zhang Department of Computer Science Rutgers University Wednesday 5 th October, 2016 Zheng Zhang 1 CS@Rutgers University
Class Information Homework 3 due today, 11:55pm EDT. Homework 3 extra-credit question will be posted before tomorrow morning. Homework set 4 and project 1 will be posted this weekend. Zheng Zhang 2 CS@Rutgers University
Review: LL(1) Grammar Define FIRST + (δ) for rule A ::= δ FIRST (δ) - {ɛ Follow(A), if ɛ FIRST (δ) FIRST (δ) otherwise A grammar is LL(1) iff for any pair of rules that correspond to the same non-terminal (A ::= α and A ::= β) implies FIRST + (α) FIRST + (β) = Zheng Zhang 3 CS@Rutgers University
Review: Recursive Descent Parsing (parse table) Parse Table Construction: A row corresponds to a non-terminal. A column corresponds to a terminal. A cell is a production rule obtained using the FIRST+ set. Example grammar: S ::= a S b ɛ FIRST + (S ::= asb): {a FIRST + (S ::= ɛ): {b, eof a b eof other S asb ɛ ɛ error Zheng Zhang 4 CS@Rutgers University
Review: Recursive Descent Parsing (pseudo code) a b eof other S asb ɛ ɛ error main: { token := next token( ); if (S( ) and token == eof) print accept else print error ; bool S( ): switch token { case a: token := next token( ); call S( ); if token == b { token := next token( ) return true; else return false; break; case eof: case b: return true; break; default: return false; How to parse input a a a b b b? Zheng Zhang 5 CS@Rutgers University
Review: Top-Down Parsing - LL(1) Basic Idea: The parse tree is constructed from the root, expanding non-terminal nodes on the tree s frontier following a Left-most derivation The input program is read from Left to right, and input tokens are read (consumed) as the program is parsed Zheng Zhang 6 CS@Rutgers University
Syntax Directed Translation Examples: 1. Interpreter 2. Code generator 3. Type checker 4. Performance estimator Use hand-written recursive descent LL(1) parser Zheng Zhang 7 CS@Rutgers University
Example: The Original Parser 1: <expr> ::= + <expr> <expr> 2: <digit> 3: <digit> :: = 0 1 2 3... 9 + 0..9 other <expr> r1 r2 error <digit> error r3 error void expr( ): // returns value of expression int val1, val2; // values switch token { case +: token := next token( ); expr( ); expr( ); case 0..9: digit( );... void digit( ): // returns value of constant switch token { case 1: token := next token( ); case 2: token := next token( );... Zheng Zhang 8 CS@Rutgers University
Example: Interpreter <expr> ::= + <expr> <expr> <digit> <digit> :: = 0 1 2 3... 9 int expr: // returns value of expression int val1, val2; // values switch token { case +: token := next token( ); val1 = expr( ); val2 = expr( ); return val1+val2; case 0..9: return digit( );... int digit: // returns value of constant switch token { case 1: token := next token( ); return 1; case 2: token := next token( ); return 2;... Zheng Zhang 9 CS@Rutgers University
Example: Interpreter What happens when you parse subprogram + 2 + 1 2? The parsing produces: 5 Zheng Zhang 10 CS@Rutgers University
Example: Simple Code Generation <expr> ::= + <expr> <expr> <digit> <digit> :: = 0 1 2 3... 9 int expr: // returns target register of operation int target reg;// fresh register int reg1, reg2; // other registers switch token { case +: token := next token( ); target reg = next register( ); reg1 = expr( ); reg2 = expr( ); CodeGen(ADD, reg1, reg2, target reg); return target reg; case 0..9: return digit( );... int digit: // returns target register of operation int target reg; // fresh register switch token { case 1: token := next token( ); target reg = next register( ); CodeGen(LOADI, 1, target reg); return target reg; case 2: token := next token( ); target reg = next register( ); CodeGen(LOADI, 2, target reg); return target reg;... Zheng Zhang 11 CS@Rutgers University
Example: Simple Code Generation What happens when you parse subprogram + 2 + 1 2? Assumption: first call to next register( ) will return 1 The parsing produces: LOADI 2 => r2 LOADI 1 => r4 LOADI 2 => r5 ADD r4, r5 => r3 ADD r2, r3 => r1 Zheng Zhang 12 CS@Rutgers University
Example: Simple Type Checker <expr> ::= + <expr> <expr> <digit> <digit> :: = 0 1 2 3... 9 string expr: // returns type expression string type1, type2; // other type expressions switch token { case +: token := next token( ); type1 = expr( ); type2 = expr( ); if (type1 == int and type2 == int ) { return int else return error ; ; case 0..9: return digit( );... string digit: // returns type expression switch token { case 1: token := next token( ); return int ; case 2: token := next token( ); return int ;... Zheng Zhang 13 CS@Rutgers University
Example: Simple Type Checker What happens when you parse subprogram + 2 + 1 2? The parsing produces: int Zheng Zhang 14 CS@Rutgers University
Example: Basic Performance Predictor <expr> ::= + <expr> <expr> <digit> <digit> :: = 0 1 2 3... 9 int expr: // returns cycles needed to compute expression int cyc1, cyc2; // subexpression cycles switch token { case +: token := next token( ); cyc1 = expr( ); cyc2 = expr( ); return cyc1+cyc2+2 // ADD takes 2 cycles; case 0..9: return digit( );... int digit: // returns cycles switch token { case 1: token := next token( ); return 1; // LOADI takes 1 cycle case 2: token := next token( ); return 1; // LOADI takes 1 cycle... Zheng Zhang 15 CS@Rutgers University
Example: Basic Performance Predictor What happens when you parse subprogram + 2 + 1 2? The parsing produces: 7 Zheng Zhang 16 CS@Rutgers University
Imperative Programming Languages Imperative: Sequence of state-changing actions. Manipulate an abstract machine with: 1. Variables naming memory locations 2. Arithmetic and logical operations 3. Reference, evaluate, assign operations 4. Explicit control flow statements Key operations: Assignment and Goto Fits the von Neumann architecture closely Von Neumann Architecture Zheng Zhang 17 CS@Rutgers University
C: An Imperative Programming Language Expressions: include procedure and function calls and assignments, and thus can have side-effects Control Structures: if statements, with and without else clauses loops, with break and continue exits switch statements while ( <expr> ) <stmt> do <stmt> while ( <expr> ) for ( <expr> ; <expr> ; <expr> ) <stmt> goto with labelled branch targets Zheng Zhang 18 CS@Rutgers University
Data Types in C Primitives: char, int, float, double no Boolean (if it is not C99) any nonzero value is true Aggregates: arrays, structures char a[10], b[2][10]; struct rectangle { struct point p1; struct point p2; Enumerations: collection of sequenced values Pointers: &i address of i *p dereferenced value of p p+1 pointer arithmetic int *p, i; p = &i; *p = *p + 1; Zheng Zhang 19 CS@Rutgers University
Basic Comparison (incomplete!) C Java Basic types: Primitive types: int, double, char int, double, char, boolean Pointer (to a value) Reference (to an object) Aggregates: Aggregates: array, struct array, object (class) Control flow: Control flow if-else, switch, while, if-else, switch, while, break, continue, for, return, goto break, continue, for, return Logic operators: Logic operators:, &&,!, &&,! Logical comparisons: Logical comparisons: ==,!= ==,!= Numeric comparisons: Numeric comparisons: <>, <=, >= <>, <=, >= string as char * array String as an object Zheng Zhang 20 CS@Rutgers University
Compile and Run a C program test.c: #include <stdio.h> int main(void) { int x, y; printf("first number:\n"); scanf("%d", &x); printf("second number:\n"); scanf("%d", &y); printf("%d+%d = %d\n", x, y, x+y); printf("%d-%d = %d\n", x, y, x-y); printf("%d*%d = %d\n", x, y, x*y); return 0; Zheng Zhang 21 CS@Rutgers University
gcc test.c:./a.out gcc -o run test.c gcc -g test.c gdb a.out calls the GNU C compiler, and generates executable a.out runs the executable compiles program, and generates executable run generates a.out with debugging info run debugger on a.out; online documentation man gdb Zheng Zhang 22 CS@Rutgers University
Compile and Run a C program > gcc test.c > a.out First number: 4 Second number: 12 4+12 = 16 4-12 = -8 4*12 = 48 > START PROGRAMMING IN C NOW! Zheng Zhang 23 CS@Rutgers University
Debugging C programs rhea% gdb a.out (gdb) list 1 #include <stdio.h> 2 int main(void) 3 { 4 int x, y; 5 printf("first number:\n"); scanf("%d", &x); 6 printf("second number:\n"); scanf("%d", &y); 7 printf("%d+%d = %d\n", x, y, x+y); (gdb) break 7 Breakpoint 1 at 0x1052c: file test.c, line 7. (gdb) run Starting program: /.../a.out First number: 4 Second number: 12 Zheng Zhang 24 CS@Rutgers University
Breakpoint 1, main () at test.c:7 7 printf("%d+%d = %d\n", x, y, x+y); (gdb) print x $1 = 4 (gdb) print y $2 = 12 (gdb) cont Continuing. 4+12 = 16 4-12 = -8 4*12 = 48 Program exited normally. (gdb) quit Zheng Zhang 25 CS@Rutgers University
Next Lecture Things to do: Start programming in C. Check out the web for tutorials. Read Scott: Chap. 8.1-8.2 ; ALSU Chap. 7.1-7.3 Next time: More about programming in C. Procedure abstractions; run time stack; scoping. Zheng Zhang 26 CS@Rutgers University