Skip to content
Snippets Groups Projects
Commit 32159b5b authored by lucien.noel's avatar lucien.noel
Browse files

commit init

parents
No related branches found
No related tags found
No related merge requests found
Showing
with 646 additions and 0 deletions
/*
* Base class that represent a node inside the AST.
*/
public abstract class ASTNode {
/**
* File where it has been found
*/
private String filename = "";
/**
* Line where it has been found
*/
private int line = -1;
/**
* Column where it has been found
*/
private int column = -1;
/**
* Constructor
*/
public ASTNode(String fl, int line, int col) {
this.filename = fl;
this.line = line;
this.column = col;
}
/**
* Return the filename where it has been found
*/
public String getFilename() {
return this.filename;
}
/**
* Return the line where it has been found
*/
public int getLine() {
return this.line;
}
/**
* Return the column where it has been found
*/
public int getColumn() {
return this.column;
}
/**
* Accepts a AST visitor
*/
abstract Object accept(ASTVisitor visitor);
}
/*
* Represent an addition expression node inside the AST.
*/
public class Addition extends Arithmetique {
/**
* Constructor
*/
public Addition(Expression operandeGauche, Expression operandeDroite, String fl, int line, int col) {
super(operandeGauche, operandeDroite, fl, line, col);
}
/**
* Get the binary operator
*/
public String operateur() {
return "+";
}
/**
* Accepts a AST visitor
*/
Object accept(ASTVisitor visitor){
return visitor.visit(this);
}
}
/*
* Represent an assignment node inside the AST.
*/
public class Affectation extends Instruction {
/**
* The source operand (at its right)
*/
protected Expression source;
/**
* The destination variable or array (at its left)
*/
protected Expression destination;
/**
* Constructor
*/
public Affectation(Expression dest, Expression src, String fl, int line, int col) {
super(fl, line, col);
this.grefferSource(src);
this.grefferDestination(dest);
}
/**
* Get the source operand (at its right)
*/
public Expression getSource() {
return this.source;
}
/**
* Get the destination variable or array (at its left)
*/
public Expression getDestination() {
return this.destination;
}
/**
* Set the source operand (at its right)
*/
public void grefferSource(Expression exp) {
this.source = exp;
}
/**
* Set the destination variable or array (at its left)
*/
public void grefferDestination(Expression exp) {
this.destination = exp;
}
/**
* Accepts a AST visitor
*/
Object accept(ASTVisitor visitor){
return visitor.visit(this);
}
}
/*
* Base class that represent a binary arithmetique expression node inside the AST.
*/
public abstract class Arithmetique extends Binaire {
/**
* Constructor
*/
public Arithmetique(Expression operandeGauche, Expression operandeDroite, String fl, int line, int col) {
super(operandeGauche, operandeDroite, fl, line, col);
}
}
/*
* Base class that represent a binary expression node inside the AST.
*/
public abstract class Binaire extends Expression {
/**
* The expression at its left
*/
protected Expression operandeGauche;
/**
* The expression at its right
*/
protected Expression operandeDroite;
/**
* Constructor
*/
public Binaire(Expression operandeGauche, Expression operandeDroite, String fl, int line, int col) {
super(fl, line, col);
this.operandeGauche = operandeGauche;
this.operandeDroite = operandeDroite;
}
/**
* Get the left expression
*/
public Expression getGauche() {
return this.operandeGauche;
}
/**
* Get the right expression
*/
public Expression getDroite() {
return this.operandeDroite;
}
/**
* Get the binary operator.
* Must be implemented by the child class.
*/
public abstract String operateur();
/**
* Transform this node into a visualisable string
*/
public String toString() {
return this.operandeGauche + " " + this.operateur() + " " + this.operandeDroite;
}
}
/*
* Represent a group of instructions node inside the AST.
*/
import java.util.ArrayList;
public class Bloc extends Instruction {
/**
* The list of instructions
*/
private ArrayList<Instruction> instructions = null;
/**
* Constructor with provided list
*/
public Bloc(ArrayList<Instruction> instructions, String fl, int line, int col) {
super(fl, line, col);
this.setInstructions(instructions);
}
/**
* Empty constructor
*/
public Bloc(String fl, int line, int col) {
this(new ArrayList<Instruction>(), fl, line, col);
}
/**
* Get the list of instructions
*/
public ArrayList<Instruction> getInstructions() {
return this.instructions;
}
/**
* Set the list of instructions
*/
public void setInstructions(ArrayList<Instruction> instructions) {
this.instructions = instructions;
}
/**
* Add an instruction to this bloc
*/
public void addInstruction(Instruction instr) {
this.instructions.add(instr);
}
/**
* Get the size of instructions
*/
public int size() {
return this.instructions.size();
}
/**
* Accepts a AST visitor
*/
Object accept(ASTVisitor visitor){
return visitor.visit(this);
}
}
/*
* Represent a string of characters node inside the AST.
*/
public class Chaine extends Expression {
/**
* Value contained in this string node
*/
private String valeur;
/**
* Constructor
*/
public Chaine(String val, String fl, int line, int col) {
super(fl, line, col);
this.valeur = val;
}
/**
* Get the node value
*/
public String getValeur() {
return this.valeur;
}
/**
* Accepts a AST visitor
*/
Object accept(ASTVisitor visitor){
return visitor.visit(this);
}
}
/*
* Represent a function declaration instruction node inside the AST.
*/
public class DeclarationProgramme extends Instruction {
/**
* The declared variable identifier
*/
protected Idf identifier;
/**
* The declaration section of the function (list of DeclarationVariable)
*/
protected Bloc declarations;
/**
* The body of the function
*/
protected Bloc instructions;
/**
* Constructor
*/
public DeclarationProgramme(Idf identifier, String fl, int line, int col){
super(fl, line, col);
this.identifier = identifier;
}
/**
* Get the declared variable identifier
*/
public Idf getIdentifier() {
return this.identifier;
}
/**
* Get the declaration section of the function
*/
public Bloc getDeclaration() {
return this.declarations;
}
/**
* Get the body of the function
*/
public Bloc getInstructions() {
return this.instructions;
}
/**
* Set the declared variable identifier
*/
public void setIdentifier(Idf identifier) {
this.identifier = identifier;
}
/**
* Set the declarations section of the function
*/
public void setDeclarations(Bloc declarations) {
this.declarations = declarations;
}
/**
* Set the body of the function
*/
public void setInstructions(Bloc instructions) {
this.instructions = instructions;
}
/**
* Accepts a AST visitor
*/
Object accept(ASTVisitor visitor){
return visitor.visit(this);
}
}
/*
* Represent an equal comparaison expression node inside the AST.
*/
public class Egal extends Relation {
/**
* Constructor
*/
public Egal(Expression operandeGauche, Expression operandeDroite, String fl, int line, int col) {
super(operandeGauche, operandeDroite, fl, line, col);
}
/**
* Get the binary operator
*/
public String operateur() {
return "==";
}
/**
* Accepts a AST visitor
*/
Object accept(ASTVisitor visitor){
return visitor.visit(this);
}
}
/*
* Base class that represent an expression node inside the AST.
*/
public abstract class Expression extends ASTNode {
/**
* Constructor
*/
public Expression(String fl, int line, int col) {
super(fl, line, col);
}
}
/*
* Represent an identifier node inside the AST.
*/
public class Idf extends Expression {
/**
* Name of the
*/
private String nom;
/**
* Constructor
*/
public Idf(String nom, String fl, int line, int col) {
super(fl, line, col);
this.nom = nom;
}
/**
* Get the identifier value
*/
public String getNom() {
return this.nom;
}
/**
* Accepts a AST visitor
*/
Object accept(ASTVisitor visitor){
return visitor.visit(this);
}
}
/*
* Base class that represent an instruction node inside the AST.
*/
public abstract class Instruction extends ASTNode {
/**
* Constructor
*/
public Instruction(String fl, int line, int col) {
super(fl, line, col);
}
}
/*
* Represent a number node inside the AST.
*/
public class Nombre extends Expression {
/**
* Value contained in this number node
*/
private int valeur;
/**
* Constructor
*/
public Nombre(int val, String fl, int line, int col) {
super(fl, line, col);
this.valeur = val;
}
/**
* Get the node value
*/
public int getValeur() {
return this.valeur;
}
/**
* Accepts a AST visitor
*/
Object accept(ASTVisitor visitor){
return visitor.visit(this);
}
}
/*
* Base class that represent a binary relational expression node inside the AST.
*/
public abstract class Relation extends Binaire {
/**
* Constructor
*/
public Relation(Expression operandeGauche, Expression operandeDroite, String fl, int line, int col) {
super(operandeGauche, operandeDroite, fl, line, col);
}
}
/*
* Main program that launch the parsing.
*/
import java.io.FileReader;
public class Hepial {
public static void main(String[] arg) {
try {
String filePath = "";
String mode = "";
switch (arg.length) {
case 1:
filePath = arg[0];
mode = "genbytecode";
break;
case 2:
filePath = arg[0];
mode = arg[1];
break;
default:
throw new Exception("Usage : prg [filePath] [genbytecode | gensourcecode]");
}
parser myP = new parser(new HepialLexer(new FileReader(filePath)));
try {
DeclarationProgramme program = (DeclarationProgramme)myP.parse().value;
if (program == null)
return;
program.accept(new SemanticAnalyzer());
switch(mode){
case "genbytecode":
ByteCodeGenerator codeGenerator = new ByteCodeGenerator();
program.accept(codeGenerator);
System.out.println(codeGenerator.getByteCode());
break;
case "gensourcecode":
SourceCodeGenerator sourceGenerator = new SourceCodeGenerator();
program.accept(sourceGenerator);
System.out.println(sourceGenerator.getCode());
break;
default:
throw new Exception("Unrecognized running mode: '" + mode + "'");
}
} catch (Exception e) {
//le contenu du fichier est incorrect
System.out.println("Parse error: " + e);
e.printStackTrace();
}
} catch (Exception e) {
//le contenu du fichier est incorrect
System.out.println("Invalid file: " + e);
e.printStackTrace();
}
}
}
Makefile 0 → 100755
#Makefile of TCP project
#Author: Michaël Minelli
JAVA=java
JAVAC=javac
JFLEX=bin/jflex
JAVACUP=lib/java-cup-11a.jar
CLASSPATH=$(JAVACUP):.:./TDS:./ArbreAbstrait:./Visitors
FILE_FLEX=hepial.flex
FILE_CUP=hepial.cup
FILE_JAVA_NAME=HepialLexer
FILE_TEST_PRG_NAME=Hepial
TEST_CLASS=Hepial
CODE=Tests/test_base_with_sementic_issue.input
all : source
source : build $(CODE)
./run.sh source $(CODE)
bytecode : build $(CODE)
./run.sh bytecode $(CODE)
run : build $(CODE)
./run.sh run $(CODE)
tests: build
./Tests/run_tests.sh
build : sym.class parser.class $(FILE_JAVA_NAME).class $(FILE_TEST_PRG_NAME).class
sym.java parser.java : $(FILE_CUP)
$(JAVA) -jar $(JAVACUP) $(FILE_CUP)
%.class : %.java
$(JAVAC) -classpath $(CLASSPATH) $<
$(FILE_JAVA_NAME).java : $(FILE_FLEX)
$(JFLEX) $(FILE_FLEX)
clean :
rm -rf *class TDS/*class ArbreAbstrait/*class Visitors/*class Tests/results *~ parser.java sym.java $(FILE_JAVA_NAME).java
\ No newline at end of file
# Projet HEPIAL du cours Technique de compilation
## TODO et Astuces
En parcourants le code vous trouverez des TODO ainsi que des HINT vous rapellant ce que vous avez à faire et où.
## Utilisation du makefile
Pour afficher le code source généré à partir de l'arbre abstrait
> make source
Pour afficher le bytecode
> make bytecode
Pour compiler et exécuter du code HEPIAL
> make run
Le paramètre **CODE** permet de choisir le code HEPIAL à donner en entrée (par défaut: Tests/test_base_with_sementic_issue.input). Exemple:
> make run CODE=Tests/test_1.input
*La commande "make" correspond à la commande "make source"*
## Tests
Dans le dossier *Tests* nous vous fournissons 11 code source HEPIAL (les *.input) qui couvre l'ensemble des possibilités du langage. Avec ces codes sources, vous sont également fournis les sorties attendues pour :
- *SourceCodeGenerator* (*.source) qui réécrit le code à partir de l'arbre abstrait. **ATTENTION:** Votre résultat peut être légèrement différent du nôtre. Du moment que toutes les instructions sont présentes et dans le bon ordre, c'est tout bon.
- *ByteCodeGenerator* (*.bytecode) qui génère le bytecode Jasmin. **ATTENTION:** Votre bytecode peut contenir des différences avec le nôtre en fonction de certains choix que vous ferez à l'implémentation.
- *Output* (*.output) qui est le retour console de l'exécution du programme. **ATTENTION:** Contrairement au deux points précédent, l'exécution des codes d'exemple doit produire strictement la même sortie qu'attendue dans le fichier output.
En exécutant la commande suivante, vous pourrez lancer le test automatique sur les 11 codes sources fournis. Les sorties générées par votre projet seront contenu dans le dossier *Tests/results*
> make tests
**ATTENTION:** Aucun de ces tests ne vérifie le bon fonctionnement de l'analyse sémantique. Pensez donc à faire ces tests à la main. Pour cela vous trouverez différent code sémantiquement faux dans le dossier *Tests/SemanticErrors*
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="lib" level="project" />
</component>
</module>
\ No newline at end of file
TODO: Placez dans ce dossier toutes les classes nécessaire à la table des symboles
\ No newline at end of file
programme Program
entier x;
debutprg
x = 23456789;
y = -12;
finprg
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment