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.
The compile(String) method of the Pattern class in Java is used to create a pattern from the regular expression passed as parameter to method. Whenever you need to match a text against a regular expression pattern more than one time, create a Pattern instance using the Pattern. compile() method.
The pattern() method of the Pattern class in Java is used to get the regular expression which is compiled to create this pattern. We use a regular expression to create the pattern and this method used to get the same source expression. Syntax: public String pattern()
Core Java bootcamp program with Hands on practice The matcher() method of this class accepts an object of the CharSequence class representing the input string and, returns a Matcher object which matches the given string to the regular expression represented by the current (Pattern) object.
The bracketed characters [a-zA-Z0-9] mean that any letter (regardless of case) or digit will match. The * (asterisk) following the brackets indicates that the bracketed characters occur 0 or more times.
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]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With