CSc 109 Test 2 Wednesday 25 April 2001 SUGGESTED ANSWERS 1. (See also question 2, which uses the answer to this question) Write a class Toke which reads from an input stream and analyzes the stream one character at a time. The class should have the public method sym() which returns an int and public method next() which gets the next character in the input stream. The method sym() only returns one of four possible values: if the character read is '{' then sym() returns Toke::LPAR, if the character read is '}' then sym() returns Toke::RPAR, if the character read is '\n' then sym() returns Toke::EOLN; otherwise sym() returns Toke::JUNK. In practice, the above constants should have the values LPAR==0, RPAR==1, EOLN==2, JUNK==3. The class Toke might be used as follows: Toke t(cin); cout<good()) fin->get(ch); if(!fin->good()) ch='\n'; switch(ch){ case '{': val = LPAR; break; case '}': val = RPAR; break; case '\n': val = EOLN; break; default: val=JUNK; } } 2. Assume we have the grammar given by the following syntax diagrams. - Here I denote circles with parentheses () and boxes by | | - - - S--> ({) --> |T| -->(})--> |T| --> - - T ------------------ (T could be replaced by nothing) | | | - | +----->|S|------------> - Write a class Par which preforms a recursive descent parse on a line of text, verifying whether the line satisfies the syntax of the above diagrams. The class Par should use the class developed in question 1, on the assumption your answer to question 1 is correct. For the sample code below, the instance of Par should either write "correct" or an error message, depending on whether the text entered is correct. IT IS CRUCIAL THAT YOU USE A RECURSIVE DESCENT PARSE. Par p(cin); p.parse(); class Par{ public: Par(istream &in); void parse(); private: Toke *t; void S(); void T(); void check(bool ok, char *mess); }; Par::Par(istream &in){ t=new Toke(in); check(t!=NULL, "Heap overflow"); } void Par::S(){ if(t->sym()==Toke::LPAR){ t->next(); T(); check(t->sym()==Toke::RPAR," ')' expected"); t->next(); T(); } else check(false," '(' expected"); } void Par::T(){ switch(t->sym()){ case Toke::LPAR: S(); break; case Toke::RPAR : case Toke::EOLN : break; default: check(false, " ')' or eoln expected"); } } void Par::parse(){ S(); cout<<"Accepted\n"; } void Par::check(bool ok, char *mess){ if(!ok){ cout<<"ERROR: "<>" to the syntax of bool expression in the Simple Language. In particular, >> would be true if the absolute value of is >= the absolute value of and are stored on the stack, at StkPtr+2 and at StkPtr+1. Write the sasm code which should be generated for the expression IF >> GOTO ONE where the code for the evaluation of and ) has already been generated. To simplify matters, you may use decimal numbers to indicate addresses. For example, one might write load 240 add store 38 Hint: |a|>=|b| if and only if a*a >= b*b. Assume StkPtr=247, ONE=44, PC=31 load 249 load 249 mult load 248 load 248 mult sub branchge 44