The main stack in project 3 holds three kinds of items:
Add two more values, expr and dollar, to the enumeration of token-type values (only Project 3 uses these values) so each item on the main stack contains two fields:
Declare another stack (the handle stack) to hold the handle during each reduce step.
Declare two local integers to help determine precedence relations:
The accept state occurs when lookahead holds a token in one of the three rightmost columns of the precedence relations table and the main stack only holds an expr and the dollar terminal. If f(dollar) is less than f(of all other rows) and g(OROP) is greater than g(of the three rightmost columns) then the accept state occurs when g(lookahead) < g(OROP) and fmain == f(dollar).
The general form of project 3 is:
symbolptr expr() { int fmain ; /* f(topmost terminal on main stack) */ int ghandle ; /* g(topmost terminal on handle stack) */ Clear Main Stack ; Push dollar item onto main stack ; fmain = f(dollar) ; while(fmain > f(dollar) || g(lookahead) >= g(OROP)) { /* main while-loop */ if(fmain <= g(lookahead)) { /* Shift-step */ Push lookahead and attributes onto main stack; fmain = f(lookahead) ; Match(lookahead); } /* End of shift-step */ else { /* Reduce-step */ Clear Handle Stack ; Pop main stack and push item onto handle stack ; if(top of handle stack == expr) { Pop main stack and push item onto handle stack ; } ghandle = g(top of handle stack) ; if(top of main stack != expr) { fmain = f(top of main stack) ; } while((top of main stack == expr) || (fmain == ghandle)) { /* Continue moving handle */ Pop main stack and push item onto handle stack ; if(top of main stack != expr) { fmain = f(top of main stack) ; } if(top of handle stack != expr) { ghandle = g(top of handle stack) ; } } /* End moving handle */ Reduce the handle on the handle stack and push left-hand-side expr of production onto the main stack ; } /* End reduce-step */ } /* End of main while-loop */ return symbol-table-pointer on top of main stack ; } /* End of project 3