of 19
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