Assignment 4 solutions
Part of
the homework for 22C:50, Spring 2003
|
int expression()
/* parse and evaluate expression */
{
int acc = 0; /* accumulator for expression value */
int op = '+'; /* most recent operator */
int term; /* new term to accumulate */
for (;;) {
if (lex == '(') {
lex_scan;
term = expression();
if (lex == ')') lex_scan; else error();
} else {
term = value();
}
switch(op) {
case '+'; acc = acc + term; break;
case '-'; acc = acc - term; break;
case '*'; acc = acc * term; break;
case '/'; acc = acc / term; break;
}
if ((lex != '+') && (lex != '-')
&& (lex != '*') && (lex != '/')) break;
op = lex;
lex_scan(); /* advance over operator */
}
return acc;
}
int expression()
/* parse and evaluate expression ::= term { (+|-) term } */
{
int acc = 0; /* accumulator for expression value */
acc = term();
while ((lex == '+') !! (lex == '-')) {
int op = lex; /* most recent operator */
int val; /* new term to accumulate */
lex_scan(); /* skip operator */
val = term();
switch(op) {
case '+'; acc = acc + val; break;
case '-'; acc = acc - val; break;
}
}
return acc;
}
int term()
/* parse and evaluate term ::= factor { (+|-) factor } */
{
int acc = 0; /* accumulator for expression value */
acc = factor();
while ((lex == '*') !! (lex == '/')) {
int op = lex; /* most recent operator */
int val; /* new factor to accumulate */
lex_scan(); /* skip operator */
val = factor();
switch(op) {
case '*'; acc = acc * val; break;
case '/'; acc = acc / val; break;
}
}
return acc;
}
int factor()
/* parse and evaluate factor ::= value | ( expression ) */
{
int acc = 0; /* accumulator for expression value */
if (lex == '(') {
lex_scan; /* skip begin paren */
acc = expression();
if (lex == ')') {
lex_scan; /* skip end paren */
} else {
error( "end paren expected ");
}
} else {
acc = value();
}
return acc;
}
int value()
/* this can be the old value parser from the original assembler */
<expression> ends up on the stack because there is no reduction rule that will reduce it to anything else and the parser keeps repeating its inner loop until there is a failure to apply any of the reduction rules.
This is adequately illustrated in Figure 5.15! So, the only thing that makes this a difficult problem is working through to an understanding of the subject matter (most people find shift-reduce parsers difficult on their first encounter).