Practice Final Exam Questions

  1. Which of one of these context-free grammars is regular? (@ represents the null string)
    a. S ::= 'a' T | 'b' U
       T ::= 'a' T | @
       U ::= U 'b' | 'b'
    
    b. S ::= 'a' A | B
       A ::= 'a' A | 'a'
       B ::= 'b' B | 'b'
    
    c. S ::= 'a' A 'b'
       A ::= 'a' A | 'x'
    
    d. S ::= 'x' S | 'x' A | @
       A ::= 'y' A | 'y'
    
    e. S ::= 'a' 'b' S | 'a' 'x'
    
    
    
  2. Which of the following regular expressions describes the set of all strings using {a,b,c} such that no 'a' occurs to the right of any 'c'?
    1. a*b*c*
    2. (a | b)(b | c)*
    3. (a | b)* c*
    4. a* (b | c)*
    5. (a | b)*(b | c)*
  3. Given the grammar below, which one of the following is valid (can be derived from the grammar)?
    Note: 5, 8, 6, etc. are all to be treated as instances of the 'int' terminal for the grammar.
     S ::= F S S | 'int'
     F ::= '+' | '-' | '*' | '/'
    
    1. / + 5 8 - * 6 + - 12 10 2
    2. / + * 5 8 + 6 12 10 2
    3. / + * + 5 8 6 12 - 10 2
    4. / 5 8 6 12 - 10 2 + * +
    5. / + * + 5 8 6 12 10 - 2
    1. 5 8 + 6 * 12 + 10 / 2 -
    2. 5 8 6 + * 12 + 10 2 - / +
    3. 5 8 + 6 * 12 + 10 2 - /
    4. 5 8 + 6 * 12 + 10 2 - /
    5. 5 + 8 6 * 12 + 10 2 - /
  4. For the grammar below, give a right-most derivation for the postfix expression:
     S ::= S S F | 'int'
     F ::= '+' | '-' | '*' | '/'
    
    Give a derivation for 5 8 + 6 * 12 + 10 2 - /
    
    5, 8, etc. all correspond to the 'int' terminal of the grammar.
    
    You can write int5, int8, etc. to indicate
    which 'int' is indicated.
    
  5. Which two of the following is a corrrect definition of an ambiguous grammar?
    1. A grammar is ambiguous if there are two distinct sentences that can be derived using the grammar.
    2. A grammar is ambiguous if there are two distinct parse trees that can be constructed using the grammar.
    3. A grammar is ambiguous if there is some sentence in the language of the grammar that has two different derivations.
    4. A grammar is ambiguous if there is some sentence in the language of the grammar that has two different parse trees.
    5. A grammar is ambiguous if there is some sentence in the language of the grammar that has two different right-most derivations.
  6. Which two of the following grammars is ambiguous?
    a. S ::= 'a' S S | 'x'
    
    b. S ::= S 'a' S | 'x'
    
    c. S ::= S S 'a' | 'x'
    
    d. S ::= 'if' 'cond' 'then' S 'else' S | 'a'
    
    e. S ::= 'a' S | 'b' S | 'x'
    
  7. Assume static scope binding using the most-closely-nested rule and give the output for the following:
    int k = 0;
    int j = 1;
    int a[] = {10,20,30};
    void f()
    {
      a[j]++;
      a[k]++;
    }
    
    int main()
    {
      int k = 1;
      j++;
      f();
      print(a[0],a[1],a[2]);
    }
    
  8. Assume static scope binding and that parameters are passed by value-result. What is the output of the following:
    int k = 0;
    int a[] = {5,10,15,20};
    void f(int x, int y)
    {
      k++;
      x++;
      y++;
      a[k] = x + y;
    }
    main()
    {
      int k = 1;
      f(k,a[k]);
      print(k,a[0],a[1],a[2],a[3]);
    }
    
    
    1. 2 5 11 15 20
    2. 1 5 13 15 20
    3. 2 5 13 15 20
    4. 2 5 18 16 20
    5. 3 5 10 15 24
  9. Repeat the previous problem assuming parameters are passed by reference.
  10. Repeat the previous problem assuming parameters are passed by name.
  11. Repeat the previous problem assuming paramters are passed by macro-expansion.
  12. Given the two overloaded functions f, whose types are given below, give an example of a call to f that would be legal if either version was the only one, but is illegal if both are defined. (Assume C++ overload resolution rules.)
      version 1: void f(int, double);
      version 2: void f(char, float);
    
  13. Given the two overloaded functions f, whose types are given below, and the call f('A', 5), which of the descriptions of overload resolutions is correct? (Assume Java overload resolution rules.)
      version 1: void f(int, double);
      version 2: void f(char, float);
    
    call: f('A', 5)
    
    1. Only the first version is admissible and that is the version that is called.
    2. Only the second version is admissible and that is the version that is called.
    3. Neither version is admissible and the call is illegal.
    4. Both versions are admissible and the call is illegal.
    5. Both versions are admissible but version 2 is called.
    6. Both versions are admissible but version 1 is called.
  14. Which two of the following ML functions is polymorphic?
    
    a. fun f(x) = ( x + 1 );
    
    b. fun f(x,y) = 
       (
         if x = 0 then
    	 y
         else
    	 f(x-1, real(x) * y)
       );
    
    c. fun f(x,y) = 
       (
          if null(x) then
    	   y
          else
    	   f(tl(x), hd(x)::y)
       );
    
    d. fun f(x,g) = 2.0 * g(x+1);
    
    e. fun f(g,x,y) =
    (
      if null(y) then
         [x]
      else if g(x, hd(y)) then
        x::y
      else
        hd(y)::f(g,x, tl(y))
    );
    
  15. The c++ code below is an example of which one of these
    1. a type error detected by the compiler
    2. a type error detected by the run time environment when the program runs
    3. a dangling pointer
    4. a memory leak
    5. none of these
    int main()
    {
      int *p, *q;
    
      p = new int(5);
      q = p;
      delete p;
      cout << *q << endl;
    }
    
  16. Which two of the following is true?
    1. use more space than an equivalent non-tail-recursive function
    2. use less space than an equivalent non-tail-recursive function
    3. use the same space as an equivalent non-tail-recursive function
    4. use more space than an equivalent function that uses a loop
    5. use less space than an equivalent function that uses a loop
    6. use similar space as an equivalent function that uses a loop
  17. Which two of the following functions is not tail-recursive?
    a. fun f(x,y) = 
       (
          if x = 0 then
    	 y + 1
          else
    	 f(x-1, f(x+1, y-1))
       );
    
    
    b. fun f(x,y) = 
       (
         if x = 0 then
    	 y
         else
    	 f(x-1, real(x) * y)
       );
    
    c. fun f(x,y) = 
       (
          if null(x) then
    	   y
          else
    	   f(tl(x), hd(x)::y)
       );
    
    d. fun f(x,y) = 
    (
      case y of
        nil => x
      | z::zs =>
        f(x + y, tl(y))
    );
      
    
    e. fun f(g,x,y) =
    (
      if null(y) then
         [x]
      else if g(x, hd(y)) then
        x::y
      else
        hd(y)::f(g,x, tl(y))
    );
    
    
  18. Write the ML function to remove all integer values from a list less than 90. That is, write the function remove below that returns a list like lst, but omitting any value < 90.
      fun remove(lst: int list) : int list =
      (
    
    
      );
    
  19. How many entries are in the virtual function table for class B?
    1. 3
    2. 4
    3. 5
    4. 6
    5. none of these
    class A                  class B : public A     
    {			 {		       
    public:			 public:		       
      A();			   B();		       
      virtual void f();	   virtual void h();    
      virtual void g();	   virtual void k();    
      virtual void h();	   void p();	       
      void q();		   void q();
    			 };                     
    };
    
    
  20. For each of the calls in method h below in class A, tell whether the call uses static or dynamic dispatch. (Assume C++ code and rules.)
    1. a.f() (at 1. in A::h)
    2. a.g() (at 2. in A::h)
    3. f() (at 3. in A::h)
    4. g() (at 4. in A::h)
    class A
    {
      virtual void f();
      void g();
      void h(A a)
      {
         a.f();   // 1.
         a.g();   // 2.
         f();     // 3.
         g();     // 4.
      }
         
    
    };
    
    class B : public A { ... };
    
    
  21. Does the call pa->f() in main below, use static dispatch or dynamic dispatch and which implementation of f is called? (Refer to the classes A and B from the previous problem.)
    int main()
    {
      A *pa;
    
      pa = new B();
      pa->g();
    }
    
  22. Give the output of the following.
    
    class A 
    {
    public:
    	virtual void hey()
    	{ cout << "A::hey "; hi(); }
    	void hi()
    	{ cout << "A::hi "; ho(); }
    	virtual void ho() 
    	{ cout << "A::ho "; }
    };
    
    class B: public A
    {
    	virtual void hey ()
    	{ cout << "B::hey "; hi(); }
    	void hi() { cout << "B::hi "; ho(); }
    	virtual void ho() 
    	{ cout << "B::ho "; }
    
    };
    
    void main()
    {
    	A x = B();
    	A* y = new B();
    	x.hey();
    	y->hey();
    
    }
    
    
  23. If a destructor executes for class B which is a subclass of A, then the destructor for A will execute next. For each of the following, tell which destructor(s) will execute. Each answer will be one of these: (i) ~A only, (ii) both ~B and ~A.
    1. delete p at line 22
    2. delete q at line 23
    
        1	class A                   class B : public A
        2	{			  {		
        3	public:			  public:		
        4	 A();			   B();		
        5	 virtual void f();	   virtual void f();
        6				  		
        7	 ~A();			   ~B();		
        8	};			  };
        9	
       10	int main()
       11	{
       12	  A *p;
       13	  A *q;
       14	
       15	  p = new A();
       16	  p->f();
       17	
       18	  q = new B();
       19	  q->f();
       20	
       21	
       22	  delete p;
       23	  delete q;
       24	
       25	  return pa;
       26	}
    
    
  24. Repeat the previous problem if the destructor ~A is declared virtual: class A { public: A(); virtual void f(); virtual ~A(); }