[go: up one dir, main page]

0% found this document useful (0 votes)
7 views4 pages

PL 03 Exercise RecursiveDescentParser

The document outlines the design of a recursive descent parser for a specified grammar, detailing the removal of left recursion and left factoring. It provides the FIRST and FOLLOW sets for the grammar's non-terminals, confirming that the grammar is LL(1). The implementation includes pseudo code for parsing functions that handle expressions, terms, and factors, along with error handling for syntax errors.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views4 pages

PL 03 Exercise RecursiveDescentParser

The document outlines the design of a recursive descent parser for a specified grammar, detailing the removal of left recursion and left factoring. It provides the FIRST and FOLLOW sets for the grammar's non-terminals, confirming that the grammar is LL(1). The implementation includes pseudo code for parsing functions that handle expressions, terms, and factors, along with error handling for syntax errors.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

‭RECURSIVE DESCENT PARSER‬

‭Design a recursive descent parser for the following grammar.‬

Axiom ::= Expr Axiom‬‭


‭ eof‬

| λ‬

Expr ::= Expr + Term‬


| Expr – Term‬

| Term‬

Term ::= Term * Factor‬


| Term / Factor‬

| Factor‬

Factor ::= (Expr)‬


|‬‭
‭ num‬

‭1‬
F‭ irst, we need to remove left recursion and left factor the grammar to obtain:‬
‭A ::= E A eof‬
| λ‬

E
‭ ::= T E’‬
E’
‭ ::= + T E’‬
| - T E’‬

| λ‬

T
‭ ::= F T’‬
T’
‭ ::= * F T’‬
| / F T’‬

| λ‬

F
‭ ::= (E)‬
|‬‭
‭ num‬

‭ ow that we have a good grammar to start working with, let’s calculate FIRST and FOLLOW‬
N
‭sets:‬

‭Nullable‬ ‭FIRST‬ ‭FOLLOW‬

‭A‬ Yes‬
‭ λ‬
‭ , num, (‬
‭ ‭$, eof‬

‭E‬ ‭No‬ ‭num, (‬ ‭num, eof, ( , )‬

‭E’‬ Yes‬
‭ λ‬
‭ , +, -‬
‭ ‭num, eof, (, )‬

‭T‬ ‭No‬ ‭num, (‬ ‭num, eof, (, ), +, -‬

‭T’‬ Yes‬
‭ λ‬
‭ , *, /‬
‭ ‭num, eof, (, ), +, -‬

‭F‬ ‭No‬ ‭num, (‬ ‭num, eof, (, ), *, /, +, -‬

‭ on-terminals‬‭A,‬‭E’‬‭and‬‭T’‬‭are‬‭nullable,‬‭but‬‭they‬‭do‬‭not‬‭overlap‬‭in‬‭their‬‭FIRST‬‭and‬ ‭FOLLOW‬
N
‭sets,‬‭so‬‭our‬‭grammar‬‭is‬‭LL(1).‬‭We‬‭can‬‭build‬‭a‬‭recursive‬‭descent‬‭parser‬‭to‬‭recognize‬‭it.‬‭We‬‭will‬
‭make‬‭use‬‭of‬‭the‬‭function‬‭ match_token‬‭as‬‭defined‬‭below.‬‭It‬‭is‬‭important‬‭to‬‭notice‬‭that‬ ‭this‬
‭function,‬ ‭as‬ ‭it‬ ‭is‬ ‭implemented,‬ ‭asks‬ ‭the‬ ‭lexical‬ ‭analyzer‬ ‭to‬ ‭provide‬ ‭the‬ ‭next‬ ‭token‬
‭(lookahead), so we need to take that into account when using it.‬

void match_token (int expected) {‬



if (lookahead != expected) {‬‭
‭ // lookahead is a global‬‭variable‬
printf (“syntax error”) ;‬

exit (0) ;‬

} else {‬

lookahead = rd_lex () ;‬‭
‭ // read the next token‬
}‬

}‬

‭2‬
‭The implementation (in pseudo code) of the recursive descent parser would be as follows:‬

void Parse_A () {‬‭


‭ //‬‭nullable‬ ‭ A ::= E A eof | lambda‬
if (lookahead‬‭∈‬‭
‭ FOLLOW (A)) {‬
return ;‬‭
‭ // λ‬
} else if (lookahead‬‭∈‬‭
‭ FIRST (E)) { // E is not nullable‬‭
!‬
Parse_E () ;‬

Parse_A () ;‬

match_token (EOF) ;‬

} else {‬

printf (“syntax error”);‬

exit (0) ;‬

}‬

}‬

void Parse_E () {‬
‭ // E ::= T E’‬

if (lookahead‬‭∈‬‭
‭ FIRST (T)) { // T is not nullable‬‭
!‬
Parse_T ();‬

Parse_E’ ();‬

} else {‬

printf (“syntax error”);‬

exit (0) ;‬

}‬

}‬

void Parse_E’ () {‬‭


‭ //‬‭nullable‬ ‭
E’ ::= + T E’ | -‬‭
T E’ | lambda‬
if (lookahead‬‭∈‬‭
‭ FOLLOW (E’)) {‬
return ;‬‭
‭ // λ‬
} else if (lookahead == PLUS) {‬

match_token (PLUS) ;‬

Parse_T () ;‬

Parse_E’ () ;‬

} else if (lookahead == MINUS) {‬

match_token (MINUS) ;‬

Parse_T () ;‬

Parse_E’ () ;‬

} else {‬

printf (“syntax error”) ;‬

exit (0) ;‬

}‬

}‬

‭3‬
void Parse_T () {‬
‭ // T ::= F T’‬

if (token‬‭∈‬‭
‭ FIRST (F)) { // F is not nullable !‬
Parse_F () ;‬

Parse_T’ () ;‬

} else {‬

printf (“syntax error”) ;‬

exit (0) ;‬

}‬

}‬

void Parse_T’ () {‬‭


‭ //‬‭nullable‬ T’ ::= * F T’
‭ | /‬‭
F T’ | lambda‬
if (lookahead‬‭∈‬ ‭
‭ FOLLOW (T’)) {‬
return ;‬‭
‭ // λ‬
} else if (lookahead == MULT) {‬

match_token (MULT) ;‬

Parse_F () ;‬

Parse_T’ () ;‬

} else if (lookahead == DIV) {‬

match_token (DIV) ;‬

Parse_F () ;‬

Parse_T’ () ;‬

} else {‬

printf (“syntax error”) ;‬

exit (0) ;‬

}‬

}‬

void Parse_F () {‬
‭ // F ::= ( E ) | num‬

if (lookahead == L_PAREN) {‬

match_token (L_PAREN) ;‬

Parse_E () ;‬

match_token (R_PAREN) ;‬

} else if (lookahead == NUM) {‬

match_token (NUM) ;‬

} else {‬

printf (“syntax error”) ;‬

exit (0) ;‬

}‬

}‬

‭4‬

You might also like