CSE 109 Test 1  Wednesday  14 November 2007
>>>>>>>>>>>>>>>>>>>>>>>>>>SUGGESTED ANSWERS<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1.  Write a program that determines whether the strings entered on the command
line are in descending lexicographical order.  If the compiled program is
stored in a.out, then the following commands would produce the output that
appears on the line following the command.

a.out
  In order by default
a.out p
  In order by default
a.out bear Bear Ant
  In order
a.out b b ant
  In order
a.out able baker are
  Out of order


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include "word.cc"
/*descending order*/
int main(int ct,char**sym){
  if(ct<3){
    cout<<"In order by default\n";
    return 0;
  }
  ct--;
    while(ct>1){
      //    if(strcmp(sym[ct],sym[ct-1])>0){ //either of these works
      if(Word(sym[ct])>Word(sym[ct-1])){
      cout<<"Out of order\n";
      return 0;
    }
    ct--;
  }
  cout<<"In order\n";

}
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

2. Assume you have available in the lex.h the declaration for the class
Lex, a lexical analyzer for the SPL++ language (recall the constants
IDENT, NUMBER, HALT, PLUS, MINUS, MUL, DIV, DOLLAR, LT, LTE, GT, GTE, EQ,
NEQ,SEQ, END, READ, WRITE, IF, LPAR,RPAR, JUMPTO, EOLN, JUNK). Write a
program that determines whether the first line of text entered at the
console obeys the following syntax diagram, where parentheses () indicate
circles and brackets [] indicated rectangles.

   Line
   -------->(<)--->[IDENT]--->(>)--->
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include "lex.h
void check(bool b,char *mess);

int main(){
  Lex lex(cin,cout);
  int token;
  token=lex.next();
  check(token==Lex::LT," '<' expected");
  token=lex.next();
  check(token==Lex::IDENT," Identifier expected");
  token=lex.next();
  check(token==Lex::GT," '>' expected");
  token=lex.next();
  check(token==Lex::EOLN," EOLN expected");
  cout<<"Successful parse";
}
void check(bool b,char *mess){
  if(!b){
    cerr<<"ERROR: "<<mess<<endl;
    exit(1);
  }
}
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
3.  Assume that you are developing the class Word, and that the declaration
  below, along with the corresponding definitions (code, not shown here),
  is how far you have gotten.  Write the declaration and definition
  (code) for overloading "+" so that the code in main below produces the
  indicated output.
class Word{
public:
  Word(char * s="");
  Word(char ch);
  Word(const Word &w);
  ~Word();
  friend ostream & operator<<(ostream & out, const Word &w);
private:
  char *str;
  static void check(bool b, char *mess);
  void copy(char *s);
};

int main(){
  Word a("my"),b(" there ");
  cout<<("Hello"+b+a+" friend\n");  //Hello there my friend
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
friend Word operator + (const Word &a,const Word &b);

Word operator + (const Word &a, const Word &b){
  Word c;
  delete []c.str;
  c.str=new char [strlen(a.str)+strlen(b.str)+1];
  c.check(c.str!=NULL,"(+) Heap overflow");
  strcpy(c.str,a.str);
  strcat(c.str,b.str);
  return c;
}
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
4.  Write a template for a class Safe that does not allow access to a variable
until it has been defined (given a value). You need only declare and define
those methods and constructors that would be needed for the program below to
compile and produce the indicated results.

int main(){
  Safe<double> u;
  Safe<int> v;
  v.set(6);
  cout<<v.get()<<" "<<v<<endl;// 6 6
  cout<<u<<endl;  //should crash, because u has yet to be assigned a value
  cout<<u.get()<<endl; //should crash, because u has yet to be assigned a value
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <iostream>
using namespace std;

template <class X>
class Safe{
public:
  Safe();
  void set(const X & t);
  X get()const;
  template <class Y>
  friend ostream & operator<<(ostream &out,const Safe<Y>&s);
private:
  X data;
  bool good;
  static void check(bool b,char *mess);
};

template <class X>
Safe<X>::Safe(){
  good=false;
}

template <class X>
void Safe<X>::set(const X &x){
  data=x;
  good=true;
}

template <class X>
X Safe<X>::get()const{
  check(good,"(get()) Undefined variable");
  return data;
}

template <class X>
ostream & operator<<(ostream &out,const Safe<X> &s){
  out<<s.get();
  return out;
}

template <class X>
void Safe<X>::check(bool b,char *mess){
    if(!b){
      cerr<<"ERROR: "<<mess<<endl;
      exit(1);
    }
}
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
