package fr.monlouyan.bakefile; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class BakefileParser { private String filename; /** * Regex pour détecter les targets et leurs dépendances. * Format : "nom : dépendance1 dépendance2" */ private static final Pattern TARGET_PATTERN = Pattern.compile("^(\\S+)\\s*:\\s*(.*)$"); /** * Regex pour détecter les lignes de commande associées à une target. * Format : " gcc -o program program.c" (ligne indentée) */ private static final Pattern COMMAND_PATTERN = Pattern.compile("^\\s+(.+)$"); public BakefileParser(String filename) { this.filename = filename; } public List parse() { List rules = new ArrayList<>(); Set phonyTargets = new HashSet<>(); if (!Files.exists(Paths.get(filename))) { System.out.println("*** No targets specified and no makefile found. Stop."); System.exit(1); } try { List lines = Files.readAllLines(Paths.get(filename)); String currentTarget = null; List dependencies = new ArrayList<>(); List commands = new ArrayList<>(); for (String line : lines) { Matcher targetMatcher = TARGET_PATTERN.matcher(line); Matcher commandMatcher = COMMAND_PATTERN.matcher(line); if (targetMatcher.matches()) { // Sauvegarde de la règle précédente si elle existe if (currentTarget != null) { rules.add(new Rule(currentTarget, dependencies, commands, phonyTargets.contains(currentTarget))); } // Nouvelle cible détectée currentTarget = targetMatcher.group(1); dependencies = new ArrayList<>(Arrays.asList(targetMatcher.group(2).trim().split("\\s+"))); commands = new ArrayList<>(); } else if (commandMatcher.matches()) { // Ligne de commande associée à la dernière cible trouvée commands.add(commandMatcher.group(1)); } } // Ajout de la dernière règle après la boucle if (currentTarget != null) { rules.add(new Rule(currentTarget, dependencies, commands, phonyTargets.contains(currentTarget))); } } catch (IOException e) { e.printStackTrace(); } return rules; } }