Générateur de parseur
This commit is contained in:
commit
90a36dc18c
10 changed files with 274 additions and 0 deletions
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
out/
|
||||
out/*
|
||||
out/*/*
|
||||
src/*.class
|
||||
generator.sh
|
22
Makefile
Normal file
22
Makefile
Normal file
|
@ -0,0 +1,22 @@
|
|||
generator: clean clean_generator
|
||||
javac src/Main.java src/Grammaire.java src/Regle.java src/Symbole.java src/IO.java
|
||||
@echo '#!/bin/bash\ncd src\njava Main ../grammaires/$$1 $$2\nif [ $$? -eq 0 ]\nthen\n\tcd ../out\n\tmkdir $$2\n\tcd ../src\n\tchmod u+x $$2.sh\n\tmv $$2.pl ../out/$$2/$$2.pl\n\tmv $$2.sh ../out/$$2/$$2.sh\n\tcd ..\nelse\n\tcd ..\nfi\n' > generator.sh
|
||||
@chmod u+x generator.sh
|
||||
|
||||
edit:
|
||||
pluma src/Main.java src/Grammaire.java src/Regle.java src/Symbole.java &
|
||||
|
||||
edit_grammaires:
|
||||
pluma grammaires/* &
|
||||
|
||||
clean:
|
||||
rm -f src/*.class
|
||||
|
||||
clean_generator:
|
||||
rm -f generator.sh
|
||||
|
||||
clean_parseurs:
|
||||
rm -f out/*/*
|
||||
rm -d -f out/*
|
||||
|
||||
clean_all: clean_generator clean clean_parseurs
|
2
grammaires/anbn
Normal file
2
grammaires/anbn
Normal file
|
@ -0,0 +1,2 @@
|
|||
S : a S b
|
||||
S : a b
|
8
grammaires/dictionnaire
Normal file
8
grammaires/dictionnaire
Normal file
|
@ -0,0 +1,8 @@
|
|||
S : int
|
||||
S : string
|
||||
S : { Assoc }
|
||||
Assoc : KeyVal AssocBis
|
||||
Assoc :
|
||||
AssocBis : , KeyVal AssocBis
|
||||
AssocBis :
|
||||
KeyVal : id = S
|
4
grammaires/test
Normal file
4
grammaires/test
Normal file
|
@ -0,0 +1,4 @@
|
|||
S : A a
|
||||
A : b C d
|
||||
A : b A
|
||||
C : e
|
35
src/Grammaire.java
Normal file
35
src/Grammaire.java
Normal file
|
@ -0,0 +1,35 @@
|
|||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class Grammaire {
|
||||
Symbole axiome;
|
||||
ArrayList<Regle> regles;
|
||||
|
||||
public Grammaire(String grammaire) throws Exception {
|
||||
this.regles = new ArrayList<>();
|
||||
|
||||
System.out.println("Création des objets Regles");
|
||||
String[] regles = grammaire.split("\n");
|
||||
Regle regle;
|
||||
int i;
|
||||
for (i=0;i<regles.length;i++) {
|
||||
regle = new Regle(regles[i]);
|
||||
if (i == 0) {
|
||||
this.axiome = regle.getPartieGauche();
|
||||
}
|
||||
this.regles.add(regle);
|
||||
}
|
||||
}
|
||||
|
||||
public String writeGrammaire() {
|
||||
String retour = "parse(Mot) :-\n\tsplit_string(Mot, \" \", \" \", List),\n\tregle_" + this.axiome.getValue() + "(List, []).\n\n";
|
||||
Iterator<Regle> iter = this.regles.iterator();
|
||||
Regle regle;
|
||||
while (iter.hasNext()) {
|
||||
regle = iter.next();
|
||||
retour = retour + regle.writeRegle() + "\n";
|
||||
}
|
||||
|
||||
return retour;
|
||||
}
|
||||
}
|
28
src/IO.java
Normal file
28
src/IO.java
Normal file
|
@ -0,0 +1,28 @@
|
|||
import java.io.*;
|
||||
|
||||
public class IO {
|
||||
public static String loadFile(File f) throws IOException {
|
||||
BufferedInputStream in = new BufferedInputStream(new FileInputStream(f));
|
||||
StringWriter out = new StringWriter();
|
||||
int b;
|
||||
while ((b=in.read()) != -1)
|
||||
out.write(b);
|
||||
out.flush();
|
||||
out.close();
|
||||
in.close();
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
public static void writeFile(String string, String name) throws IOException {
|
||||
File f = new File(name);
|
||||
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(f));
|
||||
StringReader in = new StringReader(string);
|
||||
int b;
|
||||
while ((b=in.read()) != -1)
|
||||
out.write(b);
|
||||
out.flush();
|
||||
out.close();
|
||||
in.close();
|
||||
f.createNewFile();
|
||||
}
|
||||
}
|
54
src/Main.java
Normal file
54
src/Main.java
Normal file
|
@ -0,0 +1,54 @@
|
|||
import java.io.*;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (args.length == 2) {
|
||||
System.out.println("Ouverture du ficher " + args[0]);
|
||||
File f = new File(args[0]);
|
||||
System.out.println("Lecture du la grammaire");
|
||||
String chaine = null;
|
||||
try {
|
||||
chaine = IO.loadFile(f);
|
||||
} catch (IOException e) {
|
||||
System.out.println("FATAL : Erreur lors de la lecture du ficher");
|
||||
System.exit(1);
|
||||
}
|
||||
Grammaire grammaire = null;
|
||||
System.out.println("Création de l'objet Grammaire");
|
||||
try {
|
||||
grammaire = new Grammaire(chaine);
|
||||
} catch (Exception e) {
|
||||
System.out.println("FATAL : Erreur lors de l'analyse des règles (controlez la syntaxe)");
|
||||
System.exit(2);
|
||||
}
|
||||
System.out.println("Génération du code Prolog du parseur");
|
||||
String parseur = grammaire.writeGrammaire();
|
||||
System.out.println("Ecriture du parseur dans le fichier " + args[1] + ".pl");
|
||||
try {
|
||||
IO.writeFile(parseur, args[1] + ".pl");
|
||||
} catch (IOException e) {
|
||||
System.out.println("FATAL : Erreur lors de l'écriture du fichier prolog");
|
||||
System.exit(3);
|
||||
}
|
||||
System.out.println("Création du launcher " + args[1] + ".sh");
|
||||
String laucher ="#!/bin/bash\n" +
|
||||
"swipl -s " + args[1] + ".pl -g \"parse('$1'),halt.\" 2> /dev/null\n" + "" +
|
||||
"if [ $? -eq 0 ]\n" +
|
||||
"then\n" +
|
||||
"\techo \"OK\"\n" +
|
||||
"else\n" +
|
||||
"\techo \"KO\"\n" +
|
||||
"fi\n";
|
||||
try {
|
||||
IO.writeFile(laucher, args[1] + ".sh");
|
||||
} catch (IOException e) {
|
||||
System.out.println("FATAL : Erreur lors de l'écriture du launcher");
|
||||
System.exit(4);
|
||||
}
|
||||
} else {
|
||||
System.out.println("Deux arguments requis : fichier contenant la grammaire et nom du parseur");
|
||||
System.exit(5);
|
||||
}
|
||||
}
|
||||
}
|
77
src/Regle.java
Normal file
77
src/Regle.java
Normal file
|
@ -0,0 +1,77 @@
|
|||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class Regle {
|
||||
private Symbole partieGauche;
|
||||
private ArrayList<Symbole> partieDroite;
|
||||
|
||||
public Regle(String regle) throws Exception {
|
||||
// Regle de la forme : "S : a A b"
|
||||
regle = regle + " ";
|
||||
String[] parties = regle.split(":");
|
||||
if (parties.length != 2) {
|
||||
throw new Exception("Regle illisible");
|
||||
}
|
||||
|
||||
this.partieGauche = new Symbole(parties[0].strip());
|
||||
if (this.partieGauche.isEpsilon() || this.partieGauche.isTerminal()) {
|
||||
throw new Exception("Regle illisible");
|
||||
}
|
||||
|
||||
String[] symboles = parties[1].strip().replaceAll("\\s{2,}", " ").split(" ");
|
||||
this.partieDroite = new ArrayList<>();
|
||||
if (symboles.length == 0) {
|
||||
this.partieDroite.add(new Symbole(""));
|
||||
} else {
|
||||
int i;
|
||||
for (i=0; i<symboles.length; i++) {
|
||||
this.partieDroite.add(new Symbole(symboles[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Symbole getPartieGauche() {
|
||||
return partieGauche;
|
||||
}
|
||||
|
||||
public String printRegle() {
|
||||
String retour = this.partieGauche.getValue() + " ->";
|
||||
Iterator<Symbole> iter = this.partieDroite.iterator();
|
||||
Symbole symbole;
|
||||
while (iter.hasNext()) {
|
||||
symbole = iter.next();
|
||||
retour = retour + " " + symbole.getValue();
|
||||
}
|
||||
|
||||
return retour;
|
||||
}
|
||||
|
||||
public String writeRegle() {
|
||||
String retour = "regle_" + this.partieGauche.getValue() + "(" + this.partieGauche.getValue() + "0, Retour) :-\t\t% " + this.printRegle() + "\n";
|
||||
Iterator<Symbole> iter = this.partieDroite.iterator();
|
||||
Symbole symbole;
|
||||
int i = 0;
|
||||
while (iter.hasNext()) {
|
||||
symbole = iter.next();
|
||||
if (symbole.isEpsilon()) {
|
||||
retour = retour + "\t" + this.partieGauche.getValue() + i + " = " + this.partieGauche.getValue() + (i+1) + ",\n";
|
||||
} else if (symbole.isTerminal()) {
|
||||
retour = retour + "\t" + this.partieGauche.getValue() + i + " = [\"" + symbole.getValue() + "\"|" + this.partieGauche.getValue() + (i+1) + "],\n";
|
||||
} else {
|
||||
retour = retour + "\tregle_" + symbole.getValue() + "(" + this.partieGauche.getValue() + i + ", " + this.partieGauche.getValue() + (i+1) + "),\n";
|
||||
}
|
||||
i = i+1;
|
||||
}
|
||||
retour = retour + "\t" + this.partieGauche.getValue() + i + " = Retour,!.\n";
|
||||
|
||||
return retour;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Regle{" +
|
||||
"partieGauche=" + partieGauche +
|
||||
", partieDroite=" + partieDroite +
|
||||
'}';
|
||||
}
|
||||
}
|
39
src/Symbole.java
Normal file
39
src/Symbole.java
Normal file
|
@ -0,0 +1,39 @@
|
|||
import static java.lang.Character.isUpperCase;
|
||||
|
||||
public class Symbole {
|
||||
private boolean terminal;
|
||||
private boolean epsilon;
|
||||
private String value;
|
||||
|
||||
public Symbole(String value) {
|
||||
this.value = value;
|
||||
if (this.value.isEmpty()) {
|
||||
this.terminal = false;
|
||||
this.epsilon = true;
|
||||
} else {
|
||||
this.epsilon = false;
|
||||
this.terminal = !isUpperCase(this.value.charAt(0));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isTerminal() {
|
||||
return terminal;
|
||||
}
|
||||
|
||||
public boolean isEpsilon() {
|
||||
return epsilon;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Symbole{" +
|
||||
"terminal=" + terminal +
|
||||
", epsilon=" + epsilon +
|
||||
", value='" + value + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue