Purpose:
To go over:
Recursive descent parsers
Overview:
Finish my C++ program that implements a recursive-descent parser of a simple language of cleaning one's house in English. The language can handle:
Mop the bathroom.
Wash the dishes.
Wash the dishes pots windows.
Wash the dishes pots windows. Mop the kitchen bathroom. Vacuum the bedroom foyer.
etc.
Assignment:
Please copy and paste the following:
/*--------------------------------------------------------------------------* *---- ----* *---- This file defines a recursive-descent parser for a simple ----* *---- grammar for cleaning one's house or apartment. ----* *---- ----* *---- (1) S -> WS S ----* *---- (2) S -> RS S ----* *---- (3) S -> ----* *---- (4) WS -> WV the WL period ----* *---- (5) RS -> RV the RL period ----* *---- (6) WV -> wash|scrub ----* *---- (7) RV -> vacuum|sweep|mop ----* *---- (8) WL -> WI WL ----* *---- (9) WL -> ----* *---- (10) RL -> RI RL ----* *---- (11) RL -> ----* *---- (12) WI -> dishes|pots|windows|sink|toilet|shower ----* *---- (13) RI -> hall|foyer|bedroom|kitchen|bathroom ----* *---- ----* *---- Compile with: ----* *---- g++ cleaningLang.cpp -o cleaningLang -g ----* *---- ----* *---- ---- ---- ---- ---- ---- ---- ---- ---- ----* *---- ----* *---- ----* *---- ----* *--------------------------------------------------------------------------*/ // // $ ./cleaningLang // Expression to compute: Mop the bathroom. // This house looks better already! // $ ./cleaningLang // Expression to compute: Wash the dishes. // This house looks better already! // $ ./cleaningLang // Expression to compute: Wash the dishes pots windows. // This house looks better already! // $ ./cleaningLang // Expression to compute: Wash the dishes pots windows. Mop the kitchen bathroom. Vacuum the bedroom foyer. // This house looks better already! #include #include #include #include #include #include
Please finish parseWashVerb():
It should recognize (and then delete()) the tokens for WASH_KEYWORD_SYM and SCRUB_KEYWORD_SYM.
If you detect an error then simply throw a string that describes the problem. In my code I had the following:
throw "Expected \"wash\" or \"scrub\"";
Please finish parseRoomVerb():
It should recognize (and then delete()) the tokens for VACUUM_KEYWORD_SYM, SWEEP_KEYWORD_SYM and MOP_KEYWORD_SYM.
If you detect an error then simply throw a string that describes the problem. In my code I had the following:
throw "Expected \"vacuum\", \"sweep\", \"mop\" or end";
Please finish parseWashItem():
It should recognize (and then delete()) the tokens for DISHES_KEYWORD_SYM, POTS_KEYWORD_SYM, WINDOWS_KEYWORD_SYM, SINK_KEYWORD_SYM, TOILET_KEYWORD_SYM, and SHOWER_KEYWORD_SYM.
If you detect an error then simply throw a string that describes the problem. In my code I had the following:
throw "Expected \"dishes\", \"pots\", \"windows\"," " \"sink\", \"toilet\" or \"shower\"";
Please finish parseWashList():
It should recognize grammar rules 8 and 9 above.
(8) WL -> WI WL (9) WL ->
Please finish parseRoomItem():
It should recognize (and then delete()) the tokens for HALL_KEYWORD_SYM, BEDROOM_KEYWORD_SYM, BATHROOM_KEYWORD_SYM, KITCHEN_KEYWORD_SYM, and FOYER_KEYWORD_SYM.
If you detect an error then simply throw a string that describes the problem. In my code I had the following:
throw "Expected \"hall\", \"foyer\", \"bedroom\" \"bathroom\" or \"kitchen\"";
Please finish parseRoomList():
It should recognize grammar rules 10 and 11 above.
(10) RL -> RI RL (11) RL ->
Please finish parseWashSentence():
It should recognize grammar rule 4 above. WS -> WV the WL period
If you detect an error then simply throw a string that describes the problem. In my code I had the following:
throw "Expected \"the\"";
throw "Expected \".\"";
throw "Expected \"wash\" or \"scrub\"";
Please finish parseRoomSentence():
It should recognize grammar rule 5 above. RS -> RV the RL period
If you detect an error then simply throw a string that describes the problem. In my code I had the following:
throw "Expected \"the\"";
throw "Expected \".\"";
throw "Expected \"wash\" or \"scrub\"";
Please finish parseS():
(Done for you.)
Hints:
If the same non-terminal is on the right-hand-side, then that means a recursive call to the same function.
The methods you have to help you are:
Method: | Function: |
tokenizer.peek() | It returns the symbol_ty value for the next symbol on the input stream, without changing the input stream. When you reach the end of input it returns the value END_OF_INPUT_SYM. |
tokenizer.advance() | It returns a pointer to the instance of Symbol that was next in the token stream, and internally goes to the next symbol. Once you are thru with them, all Symbol instances should be delete()d. |
getType() of Symbol | It tells what type of symbol you have, which is one of the constants of symbol_ty. |
Sample output:
If the program successfully parses the output it prints
This house looks better already!
Otherwise it should print an error message that describes the problem.
$ ./cleaningLang Expression to compute: Wash the dishes. This house looks better already! $ ./cleaningLang Expression to compute: Wash the dishes. This house looks better already! $ ./cleaningLang Expression to compute: Wash the dishes pots. This house looks better already! $ ./cleaningLang Expression to compute: wash the Expected "." $ ./cleaningLang Expression to compute: wash Expected "the" $ ./cleaningLang Expression to compute: mop. Expected "the" $ ./cleaningLang Expression to compute: Mop the kitchen Expected "."