문제

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 ArrayLists and my program will parse through the file. I'm using Matcher and have specified pattern Strings 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]

다른 팁

Sounds like you are trying to recognize and work with the grammar of another language. I tried to do this some time ago and ended up scraping my custom code and decided to use the ANTLR API instead. It really cut down the time it took to complete my project. I would recommend you go that route if applicable.

Here is the ANTLR site: http://www.antlr.org/

You are doing pattern matching when you are trying to match "if", that expects that the whole line is equal to "if", I think what you need to do is ".if." which would be looking to see if the line contains "if". Since that is the case, use the .contains() method of the string in which you are looking for various statements instead of using regex. It is more efficent.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top