#ifndef __CCCC_UTL_H
#define __CCCC_UTL_H

#include <iostream.h>
#include "cccc_stg.h"
#include "cccc_tok.h"
#include "AParser.h"

class ANTLRAbstractToken;
class ANTLRTokenPtr;

// this file declares all enumeration datatypes used in the project, and
// also the parse state class, which is used to capture information in the
// parse and transfer it to the code database for later report generation

// for each enumeration, a single character code is defined for each member
// these codes are shown in the inline comments

// the enumerations are designed to support resolution of incomplete 
// knowledge about several sections of code which relate to the same 
// object to give the most complete picture available

class AST;

// the languages which can be parsed
// only C and C++ are implemented as yet
enum Language { lAUTO, lCPLUSPLUS, lANSIC, lJAVA, lADA };
extern Language global_language, file_language;

enum Visibility { 
  vPUBLIC,vPROTECTED,vPRIVATE,vIMPLEMENTATION,  // 0123  (Booch/Rational Rose)
  vDONTKNOW,vDONTCARE,vINVALID                  // ?X* 
};
ostream& operator << (ostream&, Visibility);
istream& operator >> (istream&, Visibility&);

enum AugmentedBool { 
  abFALSE, abTRUE, abDONTKNOW, abDONTCARE, abINVALID // FT?X*
};
ostream& operator << (ostream& os, AugmentedBool ab);
istream& operator >> (istream& is, AugmentedBool& ab);

enum UseType { 
  utDECLARATION, utDEFINITION,          // Dd  of methods and classes
  utINHERITS,                           // I   inheritance, including Java 
                                        //     extends and implements relations
  utHASBYVAL, utHASBYREF,               // Hh  class data member
  utPARBYVAL, utPARBYREF,               // Pp  method parameter or return value
  utVARBYVAL, utVARBYREF,               // Vv  local variable within a method
  utTEMPLATE_NAME, utTEMPLATE_TYPE,     // Tt  for a typedef which aliases a
                                        //     template instantiation, 
                                        //     the name of the template and the
                                        //     type over which the template is
                                        //     instantiated
  utINVOKES,                            // i   C function invocation 
  utREJECTED,                           // for extents rejected by the parser
  utWITH,                               // Ada 'with' keyword context
  utDONTKNOW, utDONTCARE, utINVALID     // ?X*                      
};
ostream& operator << (ostream&, UseType);
istream& operator >> (istream&, UseType&);

// the parse state object consists of a number of strings representing 
// knowledge about the identification of the source code object currently 
// being processed, a number of flags of type AugmentedBool, and 
// items representing knowledge about the 
// concerning the object's nature, and also its visibility

enum PSString { 
  pssFILE, pssRULE, pssFLAGS, // the context of the parse
  pssMODTYPE, pssMODULE,      // the syntactic class and name of the module 
  pssUTYPE,                    // unqualified type of the current member
  pssINDIR,                   // indirection associated with the type above
  pssITYPE,                   // type qualified with indirection
  pssMEMBER, pssPARAMS,       // name, parameter list of a member
  pssDESCRIPTION,             // textual description of the relationship type
  pssLAST                     // used to dimension the array
};

enum PSFlag { 
  psfCONST, psfSTATIC, psfEXTERN, psfVIRTUAL, // AugmentedBool
  psfVISIBILITY,                              // Visibility
  psfLAST                                     // used to dimension the array
};
enum PSVerbosity { psvSILENT, psvQUIET, psvLOUD };

#define MAX_STACK_DEPTH 1000

// I have moved some actions originally embedded within the C++ grammar
// out of the grammar into the class ParseUtility defined below, so that
// other grammars can use them as well for consistency and efficiency.
// The ParseUtility::resynchronize() method provides a standardised way
// of 1) resynchronising the parser, and 2) reporting the parse error 
// which caused the problem.  Unfortunately, to do the resynchronisation
// it requires access to protected functions of ANTLRParser.
// The class ANTLR_Assisted_Parser below is a hack to enable ParseUtility
// to violate the protection of the functions required: ParseUtility is 
// passed a pointer to a real parser which is of a subclass of ANTLRParser, 
// and casts it to this artificial subclass, so as to give ParseUtility 
// friend rights and to access the protected functions.
class ANTLR_Assisted_Parser : public ANTLRParser
{
  ANTLR_Assisted_Parser(ANTLRParser& parser) : ANTLRParser(parser) {}
  friend class ParseUtility;
};

class ParseUtility {

  ANTLR_Assisted_Parser *parser;
  CCCC_String string[int(pssLAST)];
  char flag[int(psfLAST)];
  void insert_extent(ostream&, AST*, UseType);
  int trace_depth;
  
  static int stack_depth;
  static CCCC_String   stack_tokentext[MAX_STACK_DEPTH];
  static int           stack_tokenline[MAX_STACK_DEPTH];  
  static CCCC_String   stack_rules[MAX_STACK_DEPTH];

public:
  ParseUtility();

  // the following methods are used to service the standard tracein/traceout
  // and syntax error reporting calls generated by PCCTS
  void tracein(const char *rulename, int guessing, ANTLRAbstractToken *tok);
  void traceout(const char *rulename, int guessing, ANTLRAbstractToken *tok);
  void syn(ANTLRAbstractToken *tok);

  // this method consolidates the text of the next n tokens of lookahead
  CCCC_String& lookahead_text(int n);

  // this method searches for a string of tokens at the specified nesting
  // depth from the specified token class, and uses them as a marker to 
  // resynchronise the parser
  void resynchronize(
	int initial_nesting, SetWordType *resync_token_class, 
	ANTLRTokenPtr& resync_token);

  // constructors, destructors, initialisation etc.
  void reset(ANTLRParser* parser);
  ParseUtility(const ParseUtility&);
  ParseUtility& operator=(const ParseUtility&);
  virtual ~ParseUtility();
  
  // the class maintains a number of strings and flags which reflect 
  // the most recently recognized module, member, type (with and without 
  // indirection) etc, and the visibility of items occuring at the current
  // context
  const CCCC_String& get_string(PSString) const;
  void set_string(PSString, const CCCC_String& value);
  int get_flag(PSFlag) const;
  void set_flag(PSFlag,int);
  void set_flag(Visibility);

  void dump(ostream&, PSVerbosity);      

  // each of the four functions below writes one or more records into 
  // the database of code
  void record_module_extent(AST*,UseType);
  void record_function_extent(AST*,UseType);
  void record_userel_extent(AST*,UseType);
  void record_rejected_extent(AST*);

  char *flags() { return flag; }
};

#endif










