|
|
The lexical analysis of a C source program module will resolve the strings of characters on the input stream to a sequence of tokens. These tokens can be classified into the two mutually exclusive classes of operators and operands. There are two distinct ways to enumerate both of the categories of operators and operands. We can count the total times that a particular operator or operand has been used or we choose to enumerate only the first time it occurs. In a language such as C, and operator may be overloaded. That is, it may be called to serve many different duties. Take, for example, the operator "+". This operator can be used for integer operands or for real operands. Further, it can be used as a unary operator or as a binary operator. Thus, there are two distinct ways in which the unique operator count can be computed. First, we will enumerate the token "+". This will yield the metric value η1. Next we will parse the C program to determine the context in which the "+" operator has been used and reclassify each new occurrence of this operator as an integer "+", a floating point "+", etc. This will yield a nonoverloaded count of the "+" operators. The nonoverloaded operator count will be known as η3.
The occurrence of any token classified by the parser as an operator will cause N1 to increase by one. It represents the total operator appearances in a module. Function calls are considered operators (as well as operands; see Exhibit 3).
Exhibit 3: Examples with Operators
Examples | Operator |
---|---|
{ } { int a, b; char c = 'O'; a = 1; b = a + a; } { int a; int b; int c = 1 + 2; a = 2; printf("%d", a + c); } | 2 operators: { }
13 operators: { int , ; char = ; = ; = + ; } 18 operators:
{ int ; int ; int = + ; = ; printf ( + ' ) ; } |
Each occurrence of a new and distinct operator causes an increase in η1. An operator is counted independently of the adjoining operands (see Exhibit 4). Function calls play a dual role. On the one hand, they are operators; on the other hand, they return values and thus are also operands.
Exhibit 4: Examples with Unique Operators
Examples | Unique Operators |
---|---|
{ } { int a, b; char c = 'O'; a = 1; b = a + a; } { int a; int b; int c = 1 + 2; a = 2; printf("%d", a + c); } |
2 operators: { } 8 unique operators: { int ' ; char = + } 10 unique operators: { int ; = + printf ( ' ) } |
There are two ways that unique operators can be enumerated: overloaded and nonoverloaded. η3 is a special variation of the count of the number of unique operators. It represents the count of unique nonoverloaded operators. The counting rules are similar to η1. In addition, the concept of operator overloading is taken into consideration. η3 distinguishes operators that appear to be identical but are intrinsically different because of the operands they work with (see Exhibit 5).
Exhibit 5: Example with Overloaded and Unique Operators
Example | η1 | η3 |
---|---|---|
{ int i1=1, i2=2, i3; float f1=1.1, f2=2.2, f3; i3 = i1 + i2; f3 = f1 + f2; } |
8 unique overloaded operators: { int = ' ; float + } |
10 unique operators: { int =int , ; float =float +int +float } |
The following rules apply when computing this metric:
An assignment has always the type of its left-hand expression.
If there is an addition or a multiplication operation of the form:
operand-1 operator operand-2
the type of the operator is determined according to the order of precedence. The types of operand-1 and operand-2 are compared and the operation takes the higher type of both within this order. The order of precedence is:
double ⇒ float ⇒ long ⇒ int ⇒ short
Function calls are classified based on the called function's return type.
Unary operators can also be overloaded.
A character is considered an integer except in (see Exhibit 6):
A character assignment
A function declaration
Exhibit 6: Examples with Considerations
Examples | Considerations |
---|---|
char c1, c2 ; c1 = c1 + c2; char mod_1 () { } main ( ) { mod_1( ); } | = is a character assignment |
+ is an integer addition | |
A character function call | |
The total operand count is represented by N2. Each occurrence of an operand causes an increase in N2. Operands can be simple identifiers or complex structures that combine a set of identifiers. According to the C syntax, an operand is an expression. An expression is an operand if it is embedded in an operation; otherwise, only its elements can be operands. The total number of operands must not be modified in the following cases (see Exhibit 7):
Within a string constant
Within a character constant
Within a comment
Type definition
On the left-hand side in a variable declaration (including the "=" and the final ";")
Exhibit 7: Total Number of Operands
Examples | Total Number of Operands |
---|---|
a = b; a = b + c; if (a = b + c) { int a, b; int c = 1 + 2; a = 2; printf ("%d", a+c); } | Total of 2:
a b Total of 3:
a b c Total of 3:
a b c Total of 11:
a b c 1 2 a 2 printf "%d" a c |
The total number of unique operands will be denoted by η2. Unique operands are characterized by their name and type. Each occurrence of a distinct operand increases η2 by one. The total number of operands must not be modified in the following cases:
Within a string constant
Within a character constant
Within a comment
Type definition
On the left-hand side in a variable declaration (including the "=" and the final ";")
Very simply, the collection of all operand tokens is a bag. The collection of unique operations is a set.
|
|