Tom Kelliher, CS23
Mar. 19, 1996
Guessing at a solution and backing up out of a deadend.
Place 4 Queens on a 4 by 4 chess board such that no Queen can be attacked by another.
What's recursive about this?
Try it.
Pseudocode:
int place(int column)
{
   int row = 1;
   if (column > 4)
      return success;
   while (row < 5)
   {
      if safe(row, column)   // check that no attacks can occur
      {
         place queen at board[row][column];
         if (place(column + 1) == success)
            return success;
         pick up queen at board[row][column];
      }
      ++row;
   }
   return failure;
}
How would you find a route through the maze?

Representation of the maze?
Pseudocode:
int search(block)
{
   mark block "path";
   if block is goal
      return success;
   if block to north exists and is unvisited
      if (search(block to north) == success)
         return success;
   if block to east exists and is unvisited
      if (search(block to east) == success)
         return success;
   if block to south exists and is unvisited
      if (search(block to south) == success)
         return success;
   if block to west exists and is unvisited
      if (search(block to west) == success)
         return success;
   mark block "no path";
   return failure;
}
A language is a set of strings of symbols. The C++ language is the set of strings of symbols accepted by a C++ compiler.
A grammar is a set of rules describing a language. The rules tell you how to build a string belonging to the language.
Consider a simple grammar:
<expr>=<term>{+|-<term>}
<term>=<factor>{*|/<factor>}
<factor>=(<expr>)|<letter>
<letter>=a|b|c|...|z
What language is described?
Extended Backus-Naur Form (EBNF):
Expressing associativity, precedence?
Construct the derivation, parse tree, and evaluation tree for:
(a + b) * (c + d)
a + b * c + d
(a + b) * c + d
a + b * (c + d)
Relationship between a production and a recursive set of functions?
/**********************************************************************
 * expr.cc --- Convert infix expression to postfix form and indicate
 * if the infix expression was properly formed.
 *
 * This is a recursive descent parser, implementing the following
 * grammar:
 *    <expr>=<term>{+|-<term>}
 *    <term>=<factor>{*|/<factor}
 *    <factor>=(<expr>)|<letter>
 *    <letter>=a|b|c|...|z
 **********************************************************************/
#include <iostream.h>
#include <ctype.h>
void GetToken(void);
int Expression(void);
int Term(void);
int Factor(void);
char Token;   // Next character in the input stream --- one character 
              // lookahead.
/**********************************************************************
 * main()
 **********************************************************************/
int main()
{
   cout << "Type return on an otherwise empty line to exit.\n\n";
   while (1)
   {
      cout << "Expression: ";   // Read infix expression.
      GetToken();
      if (Token == '\n')   //
         return 0;
      // Parse the expression; if successful and we've read the entire line,
      // then we saw a valid expression
      if (Expression() && Token == '\n')
         cout << "\nValid expression\n";
      else
      {
         cout << "\nInvalid expression\n";
         while (Token != '\n')   // finish off the line
            GetToken();
      }
   }
   return 0;
}
/**********************************************************************
 * Expression() --- Parse an expression
 * This implements the production <expr>=<term>{+|-<term>}
 **********************************************************************/
int Expression(void)
{
   char Operator;
   if (!Term())
      return 0;
   while (Token == '+' || Token == '-')
   {
      Operator = Token;
      GetToken();   // Remove operator from input stream.
      if (!Term())
         return 0;
      cout << Operator;   // The operator is output following the
                          // operands --- converting the expression
                          // to postfix.
   }
   return 1;
}
/**********************************************************************
 * Term() --- Parse an term
 * This implements the production <term>=<factor>{*|/<factor>}
 **********************************************************************/
int Term(void)
{
   char Operator;
   if (!Factor())
      return 0;
   while (Token == '*' || Token == '/')
   {
      Operator = Token;
      GetToken();   // Remove operator from input stream.
      if (!Factor())
         return 0;
      cout << Operator;   // Postfix formulation.
   }
   return 1;
}
/**********************************************************************
 * Factor() --- Parse an factor
 * This implements the productions <factor>=(<expr>)|<letter>
 * and <letter>=a|b|c|...|z
 **********************************************************************/
int Factor(void)
{
   if (islower(Token))
   {
      cout << Token;   // Operands output immediately
      GetToken();   // Remove operand from input stream.
      return 1;
   }
   else if (Token == '(')
   {
      GetToken();   // Remove '(' from input stream.
      if (Expression() && Token == ')')   // check for parenthesized
                                          // expression
      {
         GetToken();   // Remove ')' from input stream.
         return 1;
      }
      else return 0;
   }
   else
      return 0;
}
/**********************************************************************
 * GetToken() --- read the next token from cin into the global variable
 * Token.
 **********************************************************************/
void GetToken(void)
{
   cin.get(Token);
}
Actions associated with each production?
Could we evaluate expressions?
Could we add an assignment operator?