Simple/pojo loc parser for java

J

Java coder

Hi,
i'd like to share this simple java parser. The aim is to count the 4
types of lines: blank, code, comments, javadocs and the total. If you
use it, and find flaws in it, please answer to the post.


import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;

public class JavaScanner {

public static class Count {
int nbCommentsLines;
int nbJavadocsLines;
int nbLinesCode;
int nbBlankLines;
int nbLinesTotal;

void add(Count count) {
nbJavadocsLines += count.nbJavadocsLines;
nbCommentsLines += count.nbCommentsLines;
nbLinesCode += count.nbLinesCode;
nbBlankLines += count.nbBlankLines;
nbLinesTotal += count.nbLinesTotal;
}

void printHeaders(Writer w) throws IOException {
w.write("javadocs\t");
w.write("comments\t");
w.write("loc\t");
w.write("blank\t");
w.write("total\n");
w.flush();
}

void print(Writer w) throws IOException {
w.write(nbJavadocsLines + "\t");
w.write(nbCommentsLines + "\t");
w.write(nbLinesCode + "\t");
w.write(nbBlankLines + "\t");
w.write(nbLinesTotal + "\n");
w.flush();
}
}

private boolean first = true;
private int current, next;
private final StringBuilder buffer = new StringBuilder();

public Count count(File f) throws IOException {
FileReader fr = null;
BufferedReader br = null;
try {
fr = new FileReader(f);
br = new BufferedReader(fr);
return count(br);
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException ex2) {
ex2.printStackTrace();
}
}
}
}

public Count count(Reader br) throws IOException {
first = true;

int c;
boolean inBlocComments = false;
boolean javadocs = false;
boolean javadocsInLine = false;
boolean commentsInLine = false;
boolean otherChars = false;
buffer.setLength(0);
Count count = new Count();
boolean inSingleLineComment = false;

while ((c = readChar(br)) != -1) {
// Windows : \r\n
// Mac : \r
// Unix : \n
if (c == '\r' || c == '\n') {
if (c == '\r' && next == '\n')
readChar(br); // eat up the '\n'

if (inBlocComments && !javadocs
|| commentsInLine && !javadocsInLine && !otherChars
|| inSingleLineComment) {
count.nbCommentsLines++;
//System.err.print("COMMENT : " + buffer);
} else if (inBlocComments && javadocs
|| javadocsInLine && !otherChars) {
count.nbJavadocsLines++;
//System.err.print("JAVADOC : " + buffer);
} else if (!commentsInLine && otherChars) {
count.nbLinesCode++;
//System.err.print("CODE : " + buffer);
} else if (!commentsInLine && !otherChars) {
count.nbBlankLines++;
//System.err.print("BLANK : " + buffer);
}
count.nbLinesTotal++;

if (next == -1)
return count;
otherChars = false;
if (!inBlocComments) {
commentsInLine = false;
javadocsInLine = false;
}
buffer.setLength(0);
inSingleLineComment = false;
} else if (inSingleLineComment) {

} else if (c == '*') {
if (next == '/') {
readChar(br); // loose the '/'
inBlocComments = false;
javadocs = false;
continue;
}
} else if (!inBlocComments && c == '/') {
if (next == '*') {
readChar(br); // loose the '*'

if (next == '*') {
javadocs = true;
javadocsInLine = true;
}
inBlocComments = true;
commentsInLine = true;
continue;
} else if (next == '/')
inSingleLineComment = true;
} else if (c == ' ' || c == '\t') {
} else if (!inBlocComments) {
otherChars = true;
}
}
// same as end of line
if (inBlocComments && !javadocs
|| commentsInLine && !otherChars
|| inSingleLineComment) {
count.nbCommentsLines++;
//System.err.print("COMMENT : " + buffer);
} else if (inBlocComments && javadocs
|| javadocsInLine && !otherChars) {
count.nbJavadocsLines++;
//System.err.print("JAVADOC : " + buffer);
} else if (!commentsInLine && otherChars) {
count.nbLinesCode++;
//System.err.println("CODE : " + buffer);
} else if (!commentsInLine && !otherChars) {
count.nbBlankLines++;
//System.err.println("BLANK : " + buffer);
}
count.nbLinesTotal++;
return count;
}

private int readChar(Reader r) throws IOException {
if (first) {
current = r.read();
if (current != -1)
next = r.read();
else
next = -1;
first = false;
} else {
current = next;
next = r.read();
}
if (current != -1)
buffer.append((char)current);
return current;
}
}
 
L

Lew

Java said:
i'd [sic] like to share this simple java [sic] parser. The aim is to count the 4
types of lines: blank, code, comments, javadocs [sic] and the total. If you
use it, and find flaws in it, please answer to the post.

How many comment lines does your program count for this code:

public class LineCounterBreaker
{
/** This tries to confuse the line counter.
* @param args String []
*/
public static void main( String [] args )
{
String quote commentChars = "/**";
/** This is not a Javadoc comment. */
System.out.println( "Comment chars = "+ commentChars + "/*" );
commentChars += "/*"; // is this a comment line or a non-comment
line? /*
commentChars += "//"; /* // is this a comment line? */
/** Is the next line a comment line? This is not a Javadoc
comment either */
commentChars += "/*";
}
}

Out of 16 lines I count 3 Javadoc lines, 2 comment lines, and 11
regular lines. What does your program show?
 
J

John B. Matthews

Java coder said:
i'd like to share this simple java parser. The aim is to
count the 4 types of lines: blank, code, comments, javadocs
and the total. If you use it, and find flaws in it, please
answer to the post.

[...]

Alternatively, SourceMeter [1] uses a JavaCC generated parser
to examine Java source code. I've adapted [2] it to count
constructors, fields an d methods; but the parser recognizes
SINGLE_LINE_COMMENT, MULTI_LINE_COMMENT and FORMAL_COMMENT
tokens, among others. As a side effect it detects syntactically
incorrect programs. For example,

$ unzip ../SourceMeter-0.5.zip
$ patch -p0 < ../patch6.txt
$ ant build
$ ls -1 *.java
LineCounterBreaker.java
$ java -jar SourceMeter.jar .
Java parse error

In retrospect, that's a bit cryptic; on compilable code, it's
not bad:

$ java -jar SourceMeter.jar src
FC Number of processed files
JCON Number of Java constructors
JFLD Number of Java field definitions
JMTH Number of Java method definitions
LOT Lines of text
LOTNE Non-empty lines of text

Dir FC JCON JFLD JMTH LOT LOTNE
root - - - - - -
sourcemeter 10 9 40 82 1,535 1,388
gauge 3 3 7 15 172 143
parser 1 0 0 1 34 29
java 7 13 210 579 9,653 9,006
parser 8 13 210 580 9,687 9,035
util 2 3 1 7 125 109
sourcemeter 23 28 258 684 11,519 10,675
root 23 28 258 684 11,519 10,675

[1]<http://sourceforge.net/projects/sourcemeter/>
[2]<http://sourceforge.net/tracker/?group_id=37608&atid=420208>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top