The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#ifndef RULE_H
#define RULE_H

#include <string>
#include <list>
#include <vector>
#include <iostream>
#include <typeinfo>

using namespace std;

class Rule
{
  friend class Rule_List;

public:
  virtual Rule* Clone() const = 0;

  virtual ~Rule();

  virtual void Initialize(const unsigned int in_allowed_length, const Rule* in_previous_rule = NULL);
  virtual const unsigned int Get_Allowed_Length() const;
  virtual void Reset_String();

  virtual void Invalidate();
  virtual const bool Is_Valid();
  virtual const bool Needs_Reset() const;

  virtual const bool Check_For_String();
  virtual const list<string> Get_String() const = 0;

  virtual const Rule* Get_Previous_Rule() const;
  virtual const list<const Rule*> Get_Terminals() const = 0;

  virtual const Rule* operator[](const unsigned int in_index) const = 0;

protected:
  Rule();
  Rule(const Rule &in_rule);

  virtual const Rule& operator= (const Rule &in_rule);

protected:
  const Rule* m_previous_rule;
  unsigned int m_allowed_length;
  bool m_is_valid;
  bool m_needs_reset;
};

ostream& operator<< (ostream& in_ostream,
    const vector<Rule*>& in_rule_list);
ostream& operator<< (ostream& in_ostream,
    const vector<const Rule*>& in_rule_list);
ostream& operator<< (ostream& in_ostream,
    const list<Rule*>& in_rule_list);
ostream& operator<< (ostream& in_ostream,
    const list<const Rule*>& in_rule_list);

#endif // RULE_H