RULES

- Strings are generated by rules.
- Every rule supports a "Clone" operation to make a copy at runtime
- A rule is initialized by calling "Initialize(max_allowed_length)". You must
  then call "Reset_String()" to reset it.
- After initialization, strings can be enumerated by calling
  "Check_For_String", and "Get_String". Check_For_String increments to the
  next string (if necessary), returning true if there is a next string. The
  rules for the prefix of the current string are passed as an argument to
  Check_For_String in case the generation depends on the previous rules. For
  example, generating an identifier may depend on the previously generated
  identifiers (in order to avoid generating a duplicate inadvertantly). (The
  prefix rule list is empty by default.)
- You can force Check_For_String to always return false by calling Invalidate.
  It will do so until the next call to Reset_String.

- Every rule can self-describe the minimum and maximum lengths of strings that
  it can generate. Some rules like terminals may already have this information
  prior to being initialized. Other rules like nonterminals may not have this
  information until they are initialized. Call "Can_Get_Minimum_Length" and
  "Can_Get_Maximum_Length" respectively. After being initialized, both
  functions will always return true.
- An example rule that depends on being initialized with the maximum possible
  length is "A -> b | A b". Because of the recursive definition, there is no
  natural maximum length for the generated string. As a result, the maximum
  length will be equal to the maximum possible length. Note that "A -> A" (and
  other rule lists involving rules of indeterminate size) will result in an
  infinite loop. "A -> b | A b" works because the terminal b has a definite
  size, and the length for "A" in the "A b" rule list will get increasingly
  smaller.
- Here is an example:

  A_RULE start;

  start.Initialize(max_allowed_length);

  // Can only check length after calling Initialize.
  if (max_allowed_length > start.Get_Maximum_Length() ||
      max_allowed_length < start.Get_Minimum_Length())
  {
    cerr << "The maximum length must be between " <<
      start.Get_Minimum_Length() << " and " <<
      start.Get_Maximum_Length() << endl;

    return 1;
  }

  while(start.Check_For_String())
  {
    Print_String_List(start.Get_String());
  }

- Why isn't Initialize automatically called in the constructor for the rule?
  This is because the rule lists are first "declared" and then later expanded.
  The expansion can fail if the given length is not correct for a rule in a
  rule list. In this case Check_For_String will return false.

RULE TYPES

- Two types of rules are provided: nonterminal rules and terminal rules. Both
  Nonterminal_Rule and Terminal_Rule derive from Rule.
- Terminal_Rule assumes that the length is 1, and that a terminal rule will
  only generate one string. All that needs to be done is to provide a
  definition of Get_String to specify what the string to generate will be.
- It is possible to generate a finite number of terminals by overriding
  Check_For_String to check whether number_of_strings_generated is below some
  threshold.
- Nonterminal rules are implemented using the Rule_List helper class. A
  nonterminal rules has a member called nonterminal_lists which contains lists
  of rules. For example, "A -> B C | C D" would have two rule lists in the
  nonterminal lists, one for "B C" and one for "C D".
