# 25 Recursive Descent Parsing

Embed Size (px)

Citation preview

• 8/6/2019 25 Recursive Descent Parsing

1/19

14-Jul-11

Recursive descent parsing

• 8/6/2019 25 Recursive Descent Parsing

2/19

Som e n o tes o n recursive descent

The starter c o de that I gave y o u did n o t exactly fit thegra mm ar that I gave y o u

Bo th w o rk, b o th are c o rrect

Many things can be c o ded either recursively o r iteratively

I gave y o u an iterative gra mm ar and recursive c o de

• 8/6/2019 25 Recursive Descent Parsing

3/19

Recursive rule f o r

::=

public boolean term() {if (!factor()) return false;if (!multiplyOperator()) return true;if (!term()) error("No term after '*' or '/' ");return true;

}

• 8/6/2019 25 Recursive Descent Parsing

4/19

Iterative rule f o r

::= { }

public boolean term() {if (!factor()) return false;wh ile (multiplyOperator()) {

if (!factor()) error("No factor after '*' or '/' ");}return true;

}

• 8/6/2019 25 Recursive Descent Parsing

5/19

P arse trees

Every c o nstruct (state m ent, expressi o n, etc.) in a pr o gra mm inglanguage can be represented as a parse tree

• 8/6/2019 25 Recursive Descent Parsing

6/19

Rec o gnizers and parsers

A rec o gnizer tells whether a given string bel o ngs t o (isco rrectly described by) a gra mm ar A parser uses a gra mm ar t o co nstruct a parse tree fr om a givenstring

One kind o f parser is a recursive descent parser Recursive descent parsers have s om e disadvantages:

They are n o t as fast as s om e o ther m eth o dsIt is difficult t o pr o vide really g oo d err o r m essagesThey cann o t do parses that require arbitrarily l o ng l oo kaheads

And s om e advantages:They are excepti o nally si m pleThey can be c o nstructed fr om reco gnizers si m ply by d o ing s om e extrawo rkspecifically, building a parse tree

Recursive descent parsers are great f o r quick and dirty parsing j o bs

• 8/6/2019 25 Recursive Descent Parsing

7/19

The S tack

One easy way t o do recursive descent parsing is to have each parse m eth o d take the t o kens it needs, builda parse tree , and put the parse tree o n a gl o bal stack

Write a parsem

etho

d f o

r each no

nter m

inal in the gramm

ar Each parse m etho d sh o uld get the t o kens it needs, and only tho seto kens

Tho se to kens (usually) g o o n the stack Each parse m etho d m ay call o ther parse m etho ds, and expect th o se

m etho ds t o leave their results o n the stack Each (successful) parse m etho d sh o uld leave one result o n the stack

• 8/6/2019 25 Recursive Descent Parsing

8/19

Exa m ple: wh ile state m ent

::= wh ile The parse m eth o d f o r a wh ile state m ent:

C alls the T o kenizer, which returns a while to kenMakes the while into a tree n o de, which it puts o n the stack C alls the parser f o r , which parses a c o nditi o n and puts it o nthe stack

S tack n o w co ntains: wh ile (t o p is o n right)C alls the parser f o r , which parses a bl o ck and puts it o n the stack

S tack n o w co ntains: wh ile P o ps the t o p three things fr om the stack, asse m bles the m into a tree, and

pushes this tree o nto the stack

• 8/6/2019 25 Recursive Descent Parsing

9/19

Rec o gnizing a wh ile state m ent// ::= wh ile private boolean wh ileStatement() {

if (key w ord(" wh ile")) {if (condition()) {

if (block()) {return true;

} else error("Missing '{' ");} else error("Missing ");

}return false;

}

Why d o yo u supp o se I na m ed this m eth o d wh ileStatement() instead o f wh ile() ?

• 8/6/2019 25 Recursive Descent Parsing

10/19

P arsing a wh ile state m ent// ::= wh ile private boolean wh ileStatement() {

if (key w ord(" wh ile")) {if (condition()) {

if (block()) {makeTree(3, 2, 1);return true;

} else error("Missing '{' ");} else error("Missing ");

}return false;

}

This c o de assu m es that key w ord(String) , condition() , andblock() all leave their results o n a stack On the stack, wh ile = 3, = 2, = 1

• 8/6/2019 25 Recursive Descent Parsing

11/19

Alternative c o de

public boolean wh ileStatement () {if (key w ord(" wh ile") && condition() && block()) {

makeTree(3, 2, 1);return true;

}return false;

}N o r oom f o r an err o r co nditi o n in this c o de

• 8/6/2019 25 Recursive Descent Parsing

12/19

Alternative c o de with o ne m essage

public boolean wh ileStatement() {if (key w ord(" wh ile")) {

if (condition()) && (block()) {

makeTree(3, 2, 1);return true;}error("Error in \" wh ile\" statement");

}return false;}

• 8/6/2019 25 Recursive Descent Parsing

13/19

S im ple makeTree() m eth o d

After rec o gnizing a wh ile loo p, the stack l oo kslike this:

And I c o uld have written c o de like this:private void makeTree() {

Tree rig h t = stack.pop();Tree left = stack.pop();Tree root = stack.pop();root.addC h ild(left);root.addC h ild(rig h t);

stack.push

(root);}

wh ile

This c o de assu m es that the r oo t is the third ite m do wn, etc., andthat isnt always the case

I f o und it mo re c o nvenient t o write mo re flexible m eth o ds

wh ile

• 8/6/2019 25 Recursive Descent Parsing

14/19

Mo re general makeTree m eth o dprivate void makeTree(int key w ord, int left, int rig h t) {

Tree root = getStackItem(key w ord);Tree leftC h ild = getStackItem(left);Tree rig h tCh ild = getStackItem(rig h t);

stack.pop();stack.pop();stack.pop();

root.addC h ild(leftC h ild);root.addC h ild(rig h tC h ild);stack.pus h (root);

}

• 8/6/2019 25 Recursive Descent Parsing

15/19

P arser m eth o ds

In the B NF , I have o ne l o ng definiti o n f o r ::=

| "turn"

| "take" | "drop" ...

In m y c o de, I br o ke that int o m ultiple m eth o ds ::=

| | | ...

• 8/6/2019 25 Recursive Descent Parsing

16/19

My command() m eth o d

public boolean command() {if (move()) return true;if (turn()) return true;if (take()) return true;if (drop()) return true;...return false;

}

• 8/6/2019 25 Recursive Descent Parsing

17/19

H elper m eth o ds

I wr o te a nu m ber o f helper m eth o ds f o r the P arser a nd f o r theP arserTest classesIts helpful t o have m eth o ds t o build trees quickly and easily

private makeTree(String op)

private Tree makeTree(String op, Tree left, Tree righ

t)J ava 5 all o ws a variable nu m ber o f argu m ents, s o yo u c o uld writeprivate Tree makeTree(String op, Tree... c h ildren)

An o ther useful m eth o d is assertStackTop , which is justprivate void assertStackTop(Tree expected) {

assertEquals(expected, parser.stack.peek());}

Exa m ple:Tree condition = makeTree("=", "2", "2");assertStackTop(makeTree("if", condition, "list"));

• 8/6/2019 25 Recursive Descent Parsing

18/19

F inal c omm ents

Yo u are welc om e to use any o f this c o de, but......m y c o de is never the last w o rd o n anything!C o de can a lwa ys be i m pr o ved

While I think m y c o de is generally useful, y o u alwayshave t o understand it well en o ugh t o adapt it t o yo ur particular needs

• 8/6/2019 25 Recursive Descent Parsing

19/19

The End