File: cccc_utl.h

package info (click to toggle)
cccc 3.pre81-2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 3,820 kB
  • ctags: 4,972
  • sloc: ansic: 33,244; cpp: 10,691; java: 618; makefile: 165; sh: 11
file content (282 lines) | stat: -rw-r--r-- 10,737 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
// cccc_utl.h

#ifndef __CCCC_UTL_H
#define __CCCC_UTL_H

#include "cccc.h"
#include <map>
#include <vector>
#include "cccc_tok.h"
#include "AParser.h"

class ANTLRAbstractToken;
class ANTLRTokenPtr;
class CCCC_Item;

// 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='0',vPROTECTED='1',vPRIVATE='2',vIMPLEMENTATION='3', 
  vDONTKNOW='?',vDONTCARE='X',vINVALID='*'
};
ostream& operator << (ostream&, Visibility);
istream& operator >> (istream&, Visibility&);

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

enum UseType { 
  utDECLARATION='D', utDEFINITION='d',  // of methods and classes
  utINHERITS='I',                       // inheritance, including Java 
  // extends and implements relations
  utHASBYVAL='H', utHASBYREF='h',       // class data member
  utPARBYVAL='P', utPARBYREF='p',       // method parameter or return value
  utVARBYVAL='V', utVARBYREF='v',       // local variable within a method
  utTEMPLATE_NAME='T',                  // typedef alias for a template
  utTEMPLATE_TYPE='t',                  // type over which a template is 
  // instantiated
  utINVOKES='i',                        // C function invocation 
  utREJECTED='r',                       // for extents rejected by the parser
  utWITH='w',                           // Ada 'with' keyword context
  utDONTKNOW='?', utDONTCARE='X', utINVALID='*'
};

// 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.
// This hack is necessary because the class definition we need to affect
// is generated by PCCTS: I am not proud of it and if anyone can suggest
// a way of doing without modifying PCCTS or its support code, I will be
// very happy to hear about it.
class ANTLR_Assisted_Parser : public ANTLRParser
{
  ANTLR_Assisted_Parser(ANTLRParser& parser) : ANTLRParser(parser) {}
  friend class ParseUtility;
};

// The parse utility class is intended to assist the parser in a number
// of ways.  In earlier versions, this class had at least two distinct
// roles:
// 1) as a place for common functions which each parser might call
//    for diagnostics, resynchronisation etc; and
// 2) as a general storage area for state which needs to be remembered
//    for any length of time during the parsing process.
// The class ParseStore has been added to support the second role,
// and it is hoped that the amount of stored state can be reduced
// in the near future.
class ParseUtility {

 public:
  ParseUtility(ANTLRParser *parser);
  ~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(_ANTLRTokenPtr tok, ANTLRChar *egroup, SetWordType *eset,
	   ANTLRTokenType etok, int k);

  // this method consolidates the text of the next n tokens of lookahead
  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);

  // This utility function is used to create
  // a composite scope name from a qualifier scope
  // and a relative name.
  string scopeCombine(const string& baseScope, const string& name);

  // Only one instance of this class should exist at any time.
  // This method allows the parsers and lexers to access the instance.
  static ParseUtility *currentInstance() { return theCurrentInstance; }

 private:
  static ParseUtility *theCurrentInstance;

  ANTLR_Assisted_Parser *parser;
  int trace_depth;
  static int stack_depth;
  static string   stack_tokentext[MAX_STACK_DEPTH];
  static int           stack_tokenline[MAX_STACK_DEPTH];  
  static string   stack_rules[MAX_STACK_DEPTH];

  // copy constructor and assignment operator are private to
  // prevent unexpected copying
  ParseUtility(const ParseUtility&);
  const ParseUtility& operator=(const ParseUtility&);
};

  // LOC, COM and MVG are all counted by the lexical analyzer,
  // but the counts must be apportioned after the parser has
  // identified the extents of the various declarations and definitions
  // they belong to.
  // This is achieved by the lexer maintaining counts of each
  // which are reported to the ParseUtility class on a line by line
  // basis.  ParseUtility uses this data to create a store which is
  // used to apportion counts as the parser reports extents.
  enum LexicalCount { tcCOMLINES, tcCODELINES, tcMCCABES_VG, tcLAST };


// The ParseStore class encapsulates all information storage 
// requirements related to the parser, and also manages
// the process of feeding that information to the database
// when it is complete.
// In particular, the class is responsible for receiving and
// retaining counts of the lexical metrics (LOC, COM,
// MVG) on a line-by-line basis.  These are counted in the 
// lexical analyzer, and the line-by-line counts must be 
// integrated to allocate the counts to the extents identified
// by the parser as belonging to significant declarations and
// definitions.
class ParseStore
{
 public:
  ParseStore(const string& filename);
  ~ParseStore();

  void IncrementCount(LexicalCount lc) { pendingLexicalCounts[lc]++; }
  void endOfLine(int line);


  // each of the functions below writes one or more records into 
  // the database of code
  void record_module_extent(int startLine, int endLine, 
			    const string& moduleName, 
			    const string& moduleType,
			    const string& description,
			    UseType ut);
  void record_function_extent(int startLine, int endLine, 
			      const string& returnType, 
			      const string& moduleName,
			      const string& memberName, 
			      const string& paramList,
			      const string& description,
			      Visibility visibility, 
			      UseType ut);
  void record_userel_extent(int startLine, int endLine,
			    const string& clientName, 
			    const string& memberName,
			    const string& serverName,
			    const string& description,
			    Visibility visibility,
			    UseType ut);
  void record_other_extent(int startLine, int endLine, 
			      const string& description);
  void record_file_balance_extent(string);

  // Each of the record_XXX methods above uses this function to 
  // add an extent record.
  void insert_extent(CCCC_Item&, int, int, 
		     const string&, const string&, 
		     UseType, bool allocate_lexcounts);

  // 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
  int get_flag(PSFlag) const;
  void set_flag(PSFlag,int);
  void set_flag(Visibility);
  Visibility get_visibility();
  string filename();

  char *flags() { return &(*flag.begin()); }

  // We also need the automatically generated copy constructor
  // and assignment operator to allow us to save state in the 
  // parser.

  // Only one instance of this class should exist at any time.
  // This method allows the parsers and lexers to access the instance.
  static ParseStore *currentInstance() { return theCurrentInstance; }
 private:
  static ParseStore *theCurrentInstance;

  string theFilename;

  typedef std::vector<int> LexicalCountArray;
  LexicalCountArray pendingLexicalCounts;
 
  typedef std::map<int,LexicalCountArray> LineLexicalCountMatrix;
  LineLexicalCountMatrix lineLexicalCounts;

  typedef std::vector<char> CharArray;
  CharArray flag;

  // copy constructor and assignment operator are private to
  // prevent unexpected copying
  ParseStore(const ParseStore&);
  const ParseStore& operator=(const ParseStore&);
};

#endif