I have written a program to parse a text file which contains a sample C program with if
, else
and while
condition.
I have 2 ArrayList
s and my program will parse through the file. I'm using Matcher
and have specified pattern String
s in Pattern.compile()
. I am trying to draw a control flow graph for a particular program; however, I'm just finding the nodes for now and will link them up later.
Here is my code:
//import static LineMatcher.ENCODING;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class CFG {
public void findLines(String aFileName) {
List<Integer> a = new ArrayList<Integer>();
List<Integer> b = new ArrayList<Integer>();
// int [] a = new int[10000];
// int [] b = new int[10000];
Pattern regexp = Pattern.compile("if|else|while");
Matcher exp1 = regexp.matcher("if");
Matcher exp2 = regexp.matcher("else");
Matcher exp3 = regexp.matcher("while");
Path path = Paths.get(aFileName);
try (BufferedReader reader = Files.newBufferedReader(path, ENCODING);
LineNumberReader lineReader = new LineNumberReader(reader);) {
String line = null;
while ((line = lineReader.readLine()) != null) {
// exp1.reset(line); //reset the input
int counter = 1;
if (exp1.find()) {
int l = lineReader.getLineNumber();
b.add(l);
}
if (exp2.find()) {
int l = lineReader.getLineNumber();
b.add(l);
}
if (exp3.find()) {
int l = lineReader.getLineNumber();
b.add(l);
} else {
int l = lineReader.getLineNumber();
a.add(l);
}
}
// counter++;
System.out.println(a);
System.out.println(b);
}
catch (IOException ex) {
ex.printStackTrace();
}
}
final static Charset ENCODING = StandardCharsets.UTF_8;
public static void main(String... arguments) {
CFG lineMatcher = new CFG();
lineMatcher.findLines("C:Desktop\\test.txt");
}
}
What I'm trying to do here is, if my String
is found, enter the line number in ArrayList b
, otherwise enter the line number in ArrayList a
. Hence, I know, which lines have if
, else
and while
statements.
I don't know if my code is incorrect or what, the input file is as below :
#include <stdio.h>
int main()
{
int i=1, sum = 0;
if( i = 1) {
sum += i;
} else
printf("sum = %d\n", sum);
return 0;
}
and the output of the program is:
run:
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
[1, 1, 1]
PS: I'm an amateur, this program could be logically incorrect.
Please let me know if any more information is needed.
EDIT :
Code that works fine for just one string search :
Pattern regexp = Pattern.compile("if");
Matcher matcher = regexp.matcher("if");
Path path = Paths.get(aFileName);
try (
BufferedReader reader = Files.newBufferedReader(path, ENCODING);
LineNumberReader lineReader = new LineNumberReader(reader);
){
String line = null;
while ((line = lineReader.readLine()) != null) {
matcher.reset(line); //reset the input
if(matcher.find())
{
int a= lineReader.getLineNumber();
System.out.println(a);
}
}
}
catch (IOException ex){
ex.printStackTrace();
}
Above one works fine(its just a part of code, not entire program. program is same as above one) and returns the line number where if
is found. I used same logic and added the else and while
part.
Finally, I got this working (Thanks for the amazing inputs). below are the changes I made :
public void findLines(String aFileName) {
List<Integer> a = new ArrayList<Integer>();
List<Integer> b = new ArrayList<Integer>();
Pattern regexp = Pattern.compile("(if|else|while).*");
Matcher exp1 = regexp.matcher("if|else|while");
Path path = Paths.get(aFileName);
try (
BufferedReader reader = Files.newBufferedReader(path, ENCODING);
LineNumberReader lineReader = new LineNumberReader(reader);
){
String line = null;
while ((line = lineReader.readLine()) != null) {
exp1.reset(line);
if(exp1.find())
{
int l= lineReader.getLineNumber();
b.add(l);
}
else
{int l= lineReader.getLineNumber();
a.add(l);
}
}
System.out.println(a);
System.out.println(b);
}
catch (IOException ex){
ex.printStackTrace();
}
The input file is same and the output is :
[1, 2, 3, 4, 6, 7, 8, 10, 11, 12, 13]
[5, 9]