CCCC - C and C++ Code Counter  9999-git
CCCC Development version (post-3.1.4)
cccc_tok.cc
Go to the documentation of this file.
1 /*
2  CCCC - C and C++ Code Counter
3  Copyright (C) 1994-2005 Tim Littlefair (tim_littlefair@hotmail.com)
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19 /*
20  * cccc_tok.C
21  * implementation of a token class for the cccc project
22  *
23  */
24 
25 #include "cccc.h"
26 #include "cccc_tok.h"
27 
28 /* static variables */
33 
35 
36 /*
37 ** Token objects are used to count the occurences of states which
38 ** our analyser is interested in within the text. Any metric which
39 ** can be reduced to lexical counting on the text can be recorded
40 ** this way.
41 **
42 ** This implementation counts the following features:
43 ** tokens
44 ** comment lines
45 ** lines containing at least one token of code
46 **
47 ** It also makes a lexical count for the following tokens, each of which
48 ** is expected to increase McCabe's cyclomatic complexity (Vg) for the
49 ** section of code by one unit:
50 ** IF FOR WHILE SWITCH BREAK RETURN ? && ||
51 **
52 ** Note that && and || create additional paths through the code due to C/C++
53 ** short circuit evaluation of logical expressions.
54 **
55 ** Also note the way SWITCH constructs are counted: the desired increment
56 ** in Vg is equal to the number of cases provided for, including the
57 ** default case, whether or not an action is defined for it. This is acheived
58 ** by counting the SWITCH at the head of the construct as a surrogate for
59 ** the default case, and counting BREAKs as surrogates for the individual
60 ** cases. This approach yields the correct results provided that the
61 ** coding style in use ensures the use of BREAK after all non-default
62 ** cases, and forbids 'drop through' from one case to another other than
63 ** in the case where two or more values of the switch variable require
64 ** identical actions, and no executable code is defined between the
65 ** case gates (as in the switch statement in ANTLRToken::CountToken() below).
66 */
67 
68 /* default constructor */
70  toks_alloc1++;
71  CurrentNesting=-99;
72 }
73 
74 /*
75 ** constructor used by makeToken below
76 */
78  ANTLRCommonToken(t,s) {
79  setType(t);
80  setText(s);
81  CountToken();
82 
83  toks_alloc2++;
84 }
85 
86 /* copy constructor */
88  setType(copyTok.getType());
89  setText(copyTok.getText());
90  setLine(copyTok.getLine());
92  toks_alloc3++;
93 }
94 
95 /*
96 ** the virtual pseudo-constructor
97 ** This is required because the PCCTS support code does not know the
98 ** exact nature of the token which will be created by the user's code,
99 ** and indeed does not forbid the user creating more than one kind of
100 ** token, so long as ANTLRToken is defined and all token classes are
101 ** subclassed from ANTLRAbstractToken
102 */
103 ANTLRAbstractToken *ANTLRToken::makeToken(
104  ANTLRTokenType tt, ANTLRChar *txt, int line
105  ) {
106 
107  ANTLRToken *new_t = new ANTLRToken(tt,txt);
108  if(new_t==0) {
109  cerr << "Memory overflow in "
110  "ANTLRToken::makeToken(" << static_cast<int>(tt) << ","
111  << txt << "," << line << ")" << endl;
112  exit(2);
113  }
114  new_t->setLine(line);
115 
116  DbgMsg(
117  LEXER,cerr,
118  "makeToken(tt=>" << static_cast<int>(tt) <<
119  ", txt=>" << txt <<
120  ",line=>" << line <<
121  ")" << endl
122  );
123 
124  return new_t;
125 }
126 
127 /* the destructor */
129  toks_freed++;
130  DbgMsg(MEMORY,cerr,"freeing token " << getText()
131  << " on line " << getLine()
132  << " c1:" << toks_alloc1 << " c2:" << toks_alloc2
133  << " c3:" << toks_alloc3 << " freed:" << toks_freed << endl);
134 }
135 
136 /* the assignment operator */
138  setType(copyTok.getType());
139  setText(copyTok.getText());
140  setLine(copyTok.getLine());
142  return *this;
143 }
144 
145 /*
146 ** ANTLRToken::CountToken performs counting of features which are traced
147 ** back to individual tokens created up by the lexer, i.e. the token count
148 ** and McCabes VG. Code lines and comment lines are both identified during
149 ** the processing of text which the lexer will (usually) skip, so the code
150 ** to increment these counts is in the relevant lexer rules in the file
151 ** cccc.g
152 */
154 {
155  // we have seen a non-skippable pattern => this line counts toward LOC
156  bCodeLine=1;
158  DbgMsg(COUNTER,cerr,*this);
159 }
160 
161 const char *ANTLRToken::getTokenTypeName() { return ""; }
162 
163 /*
164 ** structured output method for token objects
165 */
166 ostream& operator << (ostream& out, ANTLRToken& t) {
167  int i;
168 
169  out << "TOK: " << t.getTokenTypeName()
170  << " " << t.getText()
171  << " " << t.getLine()
172  << " " << t.getNestingLevel();
173 
174  out << endl;
175  return out;
176 }
177 
178 
179 
180 
181 
182 
183 
void CountToken()
Definition: cccc_tok.cc:153
int toks_alloc3
Definition: cccc_tok.cc:32
Definition: cccc.h:46
ANTLRToken & operator=(ANTLRToken &copyTok)
Definition: cccc_tok.cc:137
virtual ANTLRAbstractToken * makeToken(ANTLRTokenType tt, ANTLRChar *txt, int line)
Definition: cccc_tok.cc:103
static int numAllocated
Definition: cccc_tok.h:60
ostream & operator<<(ostream &out, ANTLRToken &t)
Definition: cccc_tok.cc:166
const char * getTokenTypeName()
Definition: cccc_tok.cc:161
static int bCodeLine
Definition: cccc_tok.h:65
ANTLRToken currentLexerToken
Definition: cccc_tok.cc:34
Definition: cccc.h:47
int CurrentNesting
Definition: cccc_tok.h:61
static int RunningNesting
Definition: cccc_tok.h:58
ANTLRToken()
Definition: cccc_tok.cc:69
int toks_alloc2
Definition: cccc_tok.cc:32
Definition: cccc.h:44
int toks_freed
Definition: cccc_tok.cc:32
#define DbgMsg(DF, OS, X)
Definition: cccc.h:51
int toks_alloc1
Definition: cccc_tok.cc:32
virtual ~ANTLRToken()
Definition: cccc_tok.cc:128
int getNestingLevel()
Definition: cccc_tok.h:81
ANTLRTokenType
Definition: cccc_tok.h:37