31
9/27/2006 Prof. Hilfinger, Lecture 14 1 Parsing Odds and Ends Lecture 14 (P. N. Hilfinger, plus slides adapted from R. Bodik)

9/27/2006Prof. Hilfinger, Lecture 141 Parsing Odds and Ends Lecture 14 (P. N. Hilfinger, plus slides adapted from R. Bodik)

  • View
    214

  • Download
    0

Embed Size (px)

Citation preview

9/27/2006 Prof. Hilfinger, Lecture 14 1

Parsing Odds and Ends

Lecture 14(P. N. Hilfinger, plus slides

adapted from R. Bodik)

9/27/2006 Prof. Hilfinger, Lecture 14 2

Administrivia

• Trial run of project autograder on Wednesday night (sometime). No other runs until Friday.

9/27/2006 Prof. Hilfinger, Lecture 14 3

Topics

• Syntax-directed translation and LR parsing

• Syntax-directed translation and recursive descent

• Dealing with errors in LR parsing: quick and dirty approach

9/27/2006 Prof. Hilfinger, Lecture 14 4

Syntax-Directed Translation and LR Parsing

• Idea: Add semantic stack, parallel to the parsing stack: – each symbol (terminal or non-terminal) on the parsing stack stores its value on the semantic stack

– each reduction uses the values at the top of the stack to compute the new value to be associated with the symbol that’s produced

– when the parse is finished, the semantic stack will hold just one value: the translation of the root non-terminal,which is the translation of the whole input.

9/27/2006 Prof. Hilfinger, Lecture 14 5

Semantic actions during parsing

• when shifting– push the value of the terminal on the semantic stack

• when reducing– pop k values from the semantic stack, where k is the number of symbols on production’s RHS

– push the production’s value on the semantic stack

9/27/2006 Prof. Hilfinger, Lecture 14 6

An LR example

Grammar + translation rules:

E E + ( E ) $$ = $1 + $4E int $$ = $1

Input:

2 + ( 3 ) + ( 4 )

9/27/2006 Prof. Hilfinger, Lecture 14 7

Shift-Reduce Example with evaluations

parsing stack semantic stackI int + (int) + (int)$ shift I

9/27/2006 Prof. Hilfinger, Lecture 14 8

Shift-Reduce Example with evaluations

I int + (int) + (int)$ shift I

int I + (int) + (int)$ red. E int 2 I

9/27/2006 Prof. Hilfinger, Lecture 14 9

Shift-Reduce Example with evaluations

I int + (int) + (int)$ shift I

int I + (int) + (int)$ red. E int 2 IE I + (int) + (int)$ shift 3 times 2 I

9/27/2006 Prof. Hilfinger, Lecture 14 10

Shift-Reduce Example with evaluations

I int + (int) + (int)$ shift I

int I + (int) + (int)$ red. E int 2 IE I + (int) + (int)$ shift 3 times 2 IE + (int I ) + (int)$ red. E int 2 ‘+’

‘(‘ 3 I

9/27/2006 Prof. Hilfinger, Lecture 14 11

Shift-Reduce Example with evaluations

I int + (int) + (int)$ shift I

int I + (int) + (int)$ red. E int 2 IE I + (int) + (int)$ shift 3 times 2 IE + (int I ) + (int)$ red. E int 2 ‘+’

‘(‘ 3 IE + (E I ) + (int)$ shift 2 ‘+’

‘(‘ 3 I

9/27/2006 Prof. Hilfinger, Lecture 14 12

Shift-Reduce Example with evaluations

I int + (int) + (int)$ shift I

int I + (int) + (int)$ red. E int 2 IE I + (int) + (int)$ shift 3 times 2 IE + (int I ) + (int)$ red. E int 2 ‘+’ ‘(‘

3 IE + (E I ) + (int)$ shift 2 ‘+’ ‘(‘

3 IE + (E) I + (int)$ red. E E + (E) 2

‘+’ ‘(‘ 3 ‘)’ I

9/27/2006 Prof. Hilfinger, Lecture 14 13

Shift-Reduce Example with evaluations

I int + (int) + (int)$ shift I

int I + (int) + (int)$ red. E int 2 IE I + (int) + (int)$ shift 3 times 2 IE + (int I ) + (int)$ red. E int 2 ‘+’ ‘(‘

3 IE + (E I ) + (int)$ shift 2 ‘+’ ‘(‘

3 IE + (E) I + (int)$ red. E E + (E) 2

‘+’ ‘(‘ 3 ‘)’ I E I + (int)$ shift 3 times 5 I

9/27/2006 Prof. Hilfinger, Lecture 14 14

Shift-Reduce Example with evaluations

I int + (int) + (int)$ shift Iint I + (int) + (int)$ red. E int 2 IE I + (int) + (int)$ shift 3 times 2 I E + (int I ) + (int)$ red. E int 2 ‘+’ ‘(‘

3 IE + (E I ) + (int)$ shift 2 ‘+’ ‘(‘

3 I E + (E) I + (int)$ red. E E + (E) 2 ‘+’

‘(‘ 3 ‘)’ I E I + (int)$ shift 3 times 5 IE + (int I )$ red. E int 5 ‘+’

‘(‘ 4 I

9/27/2006 Prof. Hilfinger, Lecture 14 15

Shift-Reduce Example with evaluations

I int + (int) + (int)$ shift Iint I + (int) + (int)$ red. E int 2 IE I + (int) + (int)$ shift 3 times 2 I E + (int I ) + (int)$ red. E int 2 ‘+’ ‘(‘

3 IE + (E I ) + (int)$ shift 2 ‘+’ ‘(‘

3 I E + (E) I + (int)$ red. E E + (E) 2

‘+’ ‘(‘ 3 ‘)’ I E I + (int)$ shift 3 times 5 IE + (int I )$ red. E int 5

‘+’ ‘(‘ 4 I E + (E I )$ shift 5 ‘+’ ‘(‘

4 I

9/27/2006 Prof. Hilfinger, Lecture 14 16

Shift-Reduce Example with Evaluations

I int + (int) + (int)$ shift Iint I + (int) + (int)$ red. E int 2 IE I + (int) + (int)$ shift 3 times 2 I E + (int I ) + (int)$ red. E int 2 ‘+’ ‘(‘ 3

IE + (E I ) + (int)$ shift 2 ‘+’ ‘(‘ 3 I E + (E) I + (int)$ red. E E + (E) 2 ‘+’

‘(‘ 3 ‘)’ I E I + (int)$ shift 3 times 5 IE + (int I )$ red. E int 5 ‘+’

‘(‘ 4 I E + (E I )$ shift 5 ‘+’ ‘(‘ 4 IE + (E) I $ red. E E + (E)

5 ‘+’ ‘(‘ 4 ‘)’ I

9/27/2006 Prof. Hilfinger, Lecture 14 17

Shift-Reduce Example with evaluations

I int + (int) + (int)$ shift Iint I + (int) + (int)$ red. E int 2 IE I + (int) + (int)$ shift 3 times 2 I E + (int I ) + (int)$ red. E int 2 ‘+’ ‘(‘ 3 I

E + (E I ) + (int)$ shift 2 ‘+’ ‘(‘ 3 I

E + (E) I + (int)$ red. E E + (E) 2 ‘+’ ‘(‘ 3 ‘)’ I

E I + (int)$ shift 3 times 5 IE + (int I )$ red. E int 5 ‘+’ ‘(‘

4 I E + (E I )$ shift 5 ‘+’ ‘(‘ 4 IE + (E) I $ red. E E + (E) 5 ‘+’ ‘(‘

4 ‘)’ IE I $ accept 9 I

9/27/2006 Prof. Hilfinger, Lecture 14 18

Taking Advantage of Derivation Order

• So far, rules have been functional; no side effects except to define (once) value of LHS.

• LR parsing produces reverse rightmost derivation.

• Can use the ordering to do control semantic actions with side effects.

9/27/2006 Prof. Hilfinger, Lecture 14 19

Example of Actions with Side Effects

E E + T print “+”,

E T pass

T T * F print “*”,

T F pass

F int print $1,

F ( E ) pass

We know that reduction taken after all the reductions that form the nonterminals on right-hand side.So what does this print for 3+4*(7+1)?

3 4 7 1 + * +

9/27/2006 Prof. Hilfinger, Lecture 14 20

Recursive-Descent Translation

• Translating with recursive descent is also easy.

• The semantic values (what Bison calls $$, $1, etc.), become return values of the parsing functions

• We’ll also assume that the lexer has a way to return lexical values (e.g., the scan function introduced in Lecture 9 might do so).

9/27/2006 Prof. Hilfinger, Lecture 14 21

• E T | E+T T P | T*P P int | ‘(‘ E ‘)’

def E(): T () while next() == “+”: scan(“+”); T()

def T(): P() while next() == “*”: scan(“*”); P()

Example of Recursive-Descent Translation

def P(): if next()==int: scan (int) elif next()==“(“: scan(“(“) E() scan(“)”) else: ERROR()

(we’ve cheated and used loops; see Recursive Descent for Real slidefrom lecture 9)

9/27/2006 Prof. Hilfinger, Lecture 14 22

• E T | E+T T P | T*P P int | ‘(‘ E ‘)’

def E(): v = T () while next() == “+”: scan(“+”); v += T() return vdef T(): v = P() while next() == “*”: scan(“*”); v *= P() return v

Example contd.: Add Semantic Values

def P(): if next()==int: v = scan (int) elif next()==“(“: scan(“(“) v = E() scan(“)”) else: ERROR() return v

9/27/2006 Prof. Hilfinger, Lecture 14 23

Table-Driven LL(1)

• We can automate all this, and add to the LL(1) parser method from Lecture 9.

• However, this gets a little involved, and I’m not sure it’s worth it.

• (That is, let’s leave it to the LL(1) parser generators for now!)

9/27/2006 Prof. Hilfinger, Lecture 14 24

Dealing with Syntax Errors

• One purpose of the parser is to filter out errors that show up in parsing

• Later stages should not have to deal with possibility of malformed constructs

• Parser must identify error so programmer knows what to correct

• Parser should recover so that processing can continue (and other errors found)

• Parser might even correct error (e.g., PL/C compiler could “correct” some Fortran programs into equivalent PL/1 programs!)

9/27/2006 Prof. Hilfinger, Lecture 14 25

Identifying Errors

• All of the valid parsers we’ve seen identify syntax errors “as soon as possible.”

• Valid prefix property: all the input that is shifted or scanned is the beginning of some valid program

• … But the rest of the input might not be• So in principle, deleting the lookahead (and subsequent symbols) and inserting others will give a valid program.

9/27/2006 Prof. Hilfinger, Lecture 14 26

Automating Recovery

• Unfortunately, best results require using semantic knowledge and hand tuning. – E.g., a(i].y = 5 might be turned to a[i].y = 5 if a is statically known to be a list, or a(i).y = 5 if a function.

• Some automatic methods can do an OK job that at least allows parser to catch more than one error.

9/27/2006 Prof. Hilfinger, Lecture 14 27

Bison’s Technique

• The special terminal symbol error is never actually returned by the lexer.

• Gets inserted by parser in place of erroneous tokens.

• Parsing then proceeds normally.

9/27/2006 Prof. Hilfinger, Lecture 14 28

Example of Bison’s Error Rules

• Suppose we want to throw away bad statements and carry on

stmt : whileStmt | ifStmt | …

| error NEWLINE ;

9/27/2006 Prof. Hilfinger, Lecture 14 29

Response to Error

• Consider erroneous text like if x y: …• When parser gets to the y, will detect error.

• Then pops items off parsing stack until it finds a state that allows a shift or reduction on ‘error’ terminal

• Does reductions, then shifts ‘error’.• Finally, throws away input until it finds a symbol it can shift after ‘error’

9/27/2006 Prof. Hilfinger, Lecture 14 30

Error Response, contd.

• So with our example: stmt : whileStmt

| ifStmt

| …

| error NEWLINE

;

• We see ‘y’, throw away the ‘if x’, so as to be back to where a stmt can start.

• Shift ‘error’ and away more symbols to NEWLINE. Then carry on.

Bad input: if x y: … x = 0

9/27/2006 Prof. Hilfinger, Lecture 14 31

Of Course, It’s Not Perfect

• “Throw away and punt” is sometimes called “panic-mode error recovery”

• Results are often annoying.• For example, in our example, there’s an INDENT after the NEWLINE, which doesn’t fit the grammar and causes another error.

• Bison compensates in this case by not reporting errors that are too close together

• But in general, can get cascade of errors.

• Doing it right takes a lot of work.