Parsowanie typów prymitywnych w kodzie

0

Cześć,
Robie sobie taki programik, ktory ze Stringa "code" policzy ile jest prymitywów oraz ile jest Stringów.

Prawidłowy wynik w tym przypadku to:

String -> 2 
int -> 1
double -> 1
public static void main(String[] args) {
    String code = "        String marek = \"Marek\";\n" +
            "        int integer=0;\n" +
            "\n" +
            "        // int xy = 9;\n" +
            "        // to jest komentarz int xy = 9\n" +
            "        /* cześc jak się masz */\n" +
            "        double pensja = 312.00;\n" +
            "        /*\n" +
            "        int x = 5;\n" +
            "        int y = 6;\n" +
            "         */\n" +
            "        String napis = \"int o = 0;\\n\" + \"double xo = 12; String xlz = \\\"halo\\\";\";";

    int stringCount = countOccurrences(code, "String");
    int intCount = countOccurrences(code, "int");
    int doubleCount = countOccurrences(code, "double");

    System.out.println("String -> " + stringCount);
    System.out.println("int -> " + intCount);
    System.out.println("double -> " + doubleCount);
}

private static int countOccurrences(String code, String word) {
    code = code.replaceAll("\"(\\\\.|[^\"\\\\])*\"", "");// tu są literały stringowe

    code = code.replaceAll("//.*", ""); // tu są komentarze jednoliniowe
    code = code.replaceAll("/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/", ""); // tu są komentarze blokowe

    Matcher matcher = Pattern.compile("\\b" + word + "\\b").matcher(code);
    int count = 0;
    while (matcher.find()) {
        count++;
    }
    return count;
}

Chciałbym teraz trochę ten program urozmaicić i zrobić, aby zaczytywał on z pliku xyz.java, a nie ze Stringa code.

W momencie gdy używam BufferedReadera to daje niewłaściwy odczyt.

Stworzyłem taką metodę:

private static String readCodeFromFile(String filePath) {
    StringBuilder code = new StringBuilder();
    try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
        String line;
        while ((line = reader.readLine()) != null) {
            code.append(line).append("\n");
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return code.toString();
}

I teraz po odpaleniu wynik jest:

String -> 3
int -> 1
double -> 1

W czym leży problem?

0
xwns napisał(a):

Chciałbym teraz troche ten program urozmaicić i zrobić, aby zaczytywał on z pliku xyz.java, a nie ze Stringa code.
W czym leży problem?

Ale dlaczego chcesz tak to zrobić? Jesteś jakimś krypto-fanem Apache Camel? Jeszcze zrozumiem użycie regexa vel. Pattern-Match. I piszesz, że masz to w Stringu, ale chcesz mieć to w .java. Czemu tego nie napiszesz w pliku .java po prostu i go z kodem nie skompilujesz?
i ogólnie śmietnik, w jaki sposób, ten kod ma wiedzieć, że Tobie chodzi o rozdzielenie czy to int, String, czy inny diabeł? ostatecznie i tak nadpisujesz jedną wartość

0
trojanus__ napisał(a):
xwns napisał(a):

Chciałbym teraz troche ten program urozmaicić i zrobić, aby zaczytywał on z pliku xyz.java, a nie ze Stringa code.
W czym leży problem?

Ale dlaczego chcesz tak to zrobić? Jesteś jakimś krypto-fanem Apache Camel? Jeszcze zrozumiem użycie regexa vel. Pattern-Match. I piszesz, że masz to w Stringu, ale chcesz mieć to w .java. Czemu tego nie napiszesz w pliku .java po prostu i go z kodem nie skompilujesz?
i ogólnie śmietnik, w jaki sposób, ten kod ma wiedzieć, że Tobie chodzi o rozdzielenie czy to int, String, czy inny diabeł? ostatecznie i tak nadpisujesz jedną wartość

Zrobiłem jeszcze inne rozwiązanie tak jak piszesz z Patternem.


public class Main {
    public static void main(String[] args) {

        String filePath = "sciezka_do_pliku.java";

        try {
            BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
            String line = "";
            StringBuilder javaCode = new StringBuilder();
            boolean insideCommentBlock = false;

            while ((line = bufferedReader.readLine()) != null) {
                if (line.contains("//")) {
                    insideCommentBlock = true;
                }

                if (line.contains("/*")) {
                    insideCommentBlock = true;
                }
                if (line.contains("*/")) {
                    insideCommentBlock = false;
                }
                if (!insideCommentBlock) {
                    javaCode.append(line).append("\n");
                }
            }
            bufferedReader.close();
            analyzeJavaCode(javaCode.toString());

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void analyzeJavaCode(String code) {
        Pattern variablePattern = Pattern.compile("(String|char|double|float|int|long|boolean|byte|short)\\s+[a-zA-Z_][a-zA-Z0-9_]*\\s*=\\s*[^;\n]+;");
        Matcher variableMatcher = variablePattern.matcher(code);

        Map<String, Integer> typeCounts = new HashMap<>();

        while (variableMatcher.find()) {
            String variableDeclaration = variableMatcher.group();
            String[] parts = variableDeclaration.split("\\s+");
            String variableType = parts[0];
            typeCounts.put(variableType, typeCounts.getOrDefault(variableType, 0) + 1);
        }

        for (Map.Entry<String, Integer> entry : typeCounts.entrySet()) {
            System.out.println(entry.getKey() + " -> " + entry.getValue());
        }
    }
}


W danym rozwiązaniu zliczyło mi:
double -> 2
String -> 3
int -> 1

Tu plik example:

public class Example {
    public static void main(String[] args) {
        String marek = "Marek";
        int integer=0;

        // int xy = 9;
        // to jest komentarz int xy = 9
        /* cześc jak się masz */
        double pensja = 312.00;
        /*
        int x = 5;
        int y = 6;
         */
        String napis = "int o = 0;\n" + "double xo = 12; String xlz = \"halo\";";
    }
}


Błędnie zaliczyło pogrubiony przeze mnie element:

String napis = "int o = 0;\n" + "double xo = 12; String xlz = \"halo\";";

Czyli liczy dobrze Stringa do czasu " zamkniecia, i nie uwzglednia że po + może być jego kontynuacja.

2

Przetestuj ten swój regex ze swoim inputem, np. na https://regexr.com, i zobaczysz co się dzieje.

Podpowiedź - twoja definicja "wartości zmiennej" w tym regexie to po prostu: "niepusty ciąg znaków różnych od ; i \n". A co jeśli te znaki są w środku stringa? W tej definicji musisz dodać sobie "lub ciąg dowolnych znaków zawierających się pomiędzy znakami cudzysłowu".

0

Dziękuję za pomoc, temat do zamknięcia :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1