This shows you the differences between two versions of the page.
alf:teme:tema3_java [2023/05/12 10:32] amalia.simion created |
alf:teme:tema3_java [2023/05/12 13:21] (current) amalia.simion [Devoir 4 - Sémantique] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Devoir 4 - Sémantique ====== | + | ====== Devoir 3 - Sémantique ====== |
===== Information ===== | ===== Information ===== | ||
<note important> | <note important> | ||
- | Date limite: ** le 22 mai, 23h55 ** \\ | + | Date limite: ** le 26 mai, 23h59 ** \\ |
Points: ** 2 points ** hors de la note finale \\ | Points: ** 2 points ** hors de la note finale \\ | ||
- | Téléchargez le devoir: [[https://classroom.github.com/a/P2YgEyZL | GitHub Devoir 4]] \\ | + | Téléchargez le devoir: [[https://classroom.github.com/a/QARUXoMs | GitHub Devoir 3]] \\ |
Téléchargement tardif: ** 1 point / jour ** (maximum 3 jours) \\ | Téléchargement tardif: ** 1 point / jour ** (maximum 3 jours) \\ | ||
</note> | </note> | ||
Line 18: | Line 18: | ||
- un nouvel AST avec les modifications suivantes | - un nouvel AST avec les modifications suivantes | ||
- le nouvel AST est une liste d'instructions (//statements//) | - le nouvel AST est une liste d'instructions (//statements//) | ||
- | - tous les noeuds de l'AST ont une nouvelle propriété appellée **symbol**, qui fait référence a l'entrée du tableau de symboles ou ils déclarent des variables, fonctions et types | + | - tous les noeuds de l'AST ont deux nouvelles propriétés appellée **symbol**, qui fait référence a l'entrée du tableau de symboles ou ils déclarent des variables, fonctions et types, et **errors**, qui fait référence a l'erreurs associé au noeud courant. |
- | - le programme principal s'appelle "Statements" | + | |
- | - une liste des erreurs | + | |
<note> | <note> | ||
Line 30: | Line 28: | ||
* le fichier de sortie | * le fichier de sortie | ||
<code bash> | <code bash> | ||
- | node main.js source.alf.ast.json source.alf.json | + | java ... com.example.Main source.alf.ast.json source.alf.json |
</code> | </code> | ||
Line 55: | Line 53: | ||
La table de symboles est une liste composée par des objets représentant des **contextes**. Dans l'exemple ci-dessous, on peut voir qu'il y a 2 contextes: | La table de symboles est une liste composée par des objets représentant des **contextes**. Dans l'exemple ci-dessous, on peut voir qu'il y a 2 contextes: | ||
- | * **"type": "Statements"** - le contexte du module principal, qui contient toutes les instructions | + | * - le contexte du module principal, qui contient toutes elements globale |
- | * **"type": "function"** - le contexte généré par la fonction _sum | + | * - le contexte généré par la fonction _sum |
<code javascript> | <code javascript> | ||
- | "symbol_table": [ | + | "symbolTable" : { |
- | { | + | "@class" : "org.easycompiler.semantic.SymbolTable", |
- | "variables": {}, | + | "errors" : [ "java.util.ArrayList", [ ] ], |
- | "functions": { | + | "variables" : { |
- | "_sum": { | + | "@class" : "java.util.HashMap" |
- | "type": "integer", | + | }, |
- | "parameters": [ | + | "types" : { |
- | { | + | "@class" : "java.util.HashMap" |
- | "id": "FunctionDefinitionParameter", | + | }, |
- | "type": "integer", | + | "functions" : { |
- | "name": "n1", | + | "@class" : "java.util.HashMap", |
- | "symbol": 1 | + | "_sum" : { |
- | }, | + | "@class" : "org.easycompiler.type.Function", |
- | { | + | "errors" : [ "java.util.ArrayList", [ ] ], |
- | "id": "FunctionDefinitionParameter", | + | "title" : null, |
- | "type": "integer", | + | "symbolTable" : { |
- | "name": "n2", | + | "@class" : "org.easycompiler.semantic.SymbolTable", |
- | "symbol": 1 | + | "errors" : [ "java.util.ArrayList", [ ] ], |
+ | "variables" : { | ||
+ | "@class" : "java.util.HashMap", | ||
+ | "n1" : "integer", | ||
+ | "n2" : "integer" | ||
+ | }, | ||
+ | "types" : { | ||
+ | "@class" : "java.util.HashMap", | ||
+ | "integer" : { | ||
+ | "@class" : "org.easycompiler.type.Integer", | ||
+ | "errors" : [ "java.util.ArrayList", [ ] ], | ||
+ | "title" : "integer", | ||
+ | "type" : "I64" | ||
} | } | ||
- | ], | + | }, |
- | "line": 4, | + | "functions" : { |
- | "symbol": 1 | + | "@class" : "java.util.HashMap" |
+ | } | ||
+ | }, | ||
+ | "parameters" : [ "java.util.ArrayList", [ { | ||
+ | "@class" : "org.easycompiler.ast.Property", | ||
+ | "errors" : [ "java.util.ArrayList", [ ] ], | ||
+ | "line" : 4, | ||
+ | "typeName" : "integer", | ||
+ | "title" : "n1", | ||
+ | "value" : null | ||
+ | }, { | ||
+ | "@class" : "org.easycompiler.ast.Property", | ||
+ | "errors" : [ "java.util.ArrayList", [ ] ], | ||
+ | "line" : 4, | ||
+ | "typeName" : "integer", | ||
+ | "title" : "n2", | ||
+ | "value" : null | ||
+ | } ] ], | ||
+ | "statements" : { | ||
+ | "@class" : "org.easycompiler.ast.Block", | ||
+ | "errors" : [ "java.util.ArrayList", [ ] ], | ||
+ | "line" : 4, | ||
+ | "typeName" : null, | ||
+ | "statements" : [ "java.util.ArrayList", [ ] ] | ||
+ | }, | ||
+ | "returnType" : { | ||
+ | "@class" : "org.easycompiler.type.Integer", | ||
+ | "errors" : [ "java.util.ArrayList", [ ] ], | ||
+ | "title" : "integer", | ||
+ | "type" : "I64" | ||
} | } | ||
- | }, | + | } |
- | "types": {}, | + | |
- | "type": "Statements" | + | |
- | }, | + | |
- | { | + | |
- | "variables": {}, | + | |
- | "functions": {}, | + | |
- | "types": {}, | + | |
- | "parent": 0, | + | |
- | "type": "function", | + | |
- | "function": "_sum", | + | |
- | "return_type": "integer" | + | |
} | } | ||
- | ] | + | } |
</code> | </code> | ||
- | |||
- | Lors de la création de la table de symboles, vous devez ajouter à chaque noeud AST un paramètre //symbole//, représentant l'identifiant du contexte. | ||
- | |||
==== Objet de contexte ==== | ==== Objet de contexte ==== | ||
Les objets de contexte stockent les suivantes propriétés: | Les objets de contexte stockent les suivantes propriétés: | ||
Line 114: | Line 139: | ||
* le module principal | * le module principal | ||
* une définition de fonction | * une définition de fonction | ||
- | * une classe | + | * une loop for (la variable locale utilise pour l'index) |
</note> | </note> | ||
- | |||
- | L'objet ressemble à: | ||
- | |||
- | <code javascript> | ||
- | { | ||
- | "variables": { // a dictionary of variables | ||
- | "variable_name": { | ||
- | "type": // type of the variable | ||
- | "line": // the line where the variable was declared | ||
- | "value": // the expression that the variable initially has (optional, if the define was with an assignment) | ||
- | } | ||
- | }, | ||
- | "messages": { // a dictionary of functions | ||
- | "message_name": { | ||
- | "type": // the return type of the function | ||
- | "parameters": [] // the list of parameters the function takes (the parameters node from the AST) | ||
- | "line": // the line where the function was declared | ||
- | "symbol": // the context object id that the function creates | ||
- | |||
- | } | ||
- | }, | ||
- | "types": { // a dictionary of types | ||
- | "type": { | ||
- | "type": // the type of the new type class or array | ||
- | "line": // the line where the type was declared | ||
- | // for array | ||
- | "elements_type": // the type of each array element | ||
- | "from": // the first index | ||
- | "to": // the last index | ||
- | // for class | ||
- | "elements": [ // a list of array elements (the node form the AST) | ||
- | { | ||
- | "type": | ||
- | "id": | ||
- | "line": | ||
- | }, | ||
- | ... | ||
- | ] | ||
- | } | ||
- | }, | ||
- | "parent": 0, // the parent context position in the symbol_table (except of the main script that has no parent), usually 0, | ||
- | "type": // the type of the | ||
- | "message": // the message name if this is a function context | ||
- | "class": // the class name if the context is in a message that is in a class | ||
- | "return_value": // the return type of the function if this is a function context | ||
- | } | ||
- | </code> | ||
- | |||
- | === Exemple === | ||
- | |||
- | <code javascript> | ||
- | { | ||
- | "variables": {}, | ||
- | "functions": { | ||
- | "_sum": { | ||
- | "type": "integer", | ||
- | "parameters": [ | ||
- | { | ||
- | "id": "FunctionDefinitionParameter", | ||
- | "type": "integer", | ||
- | "name": "n1", | ||
- | "symbol": 1 | ||
- | }, | ||
- | { | ||
- | "id": "FunctionDefinitionParameter", | ||
- | "type": "integer", | ||
- | "name": "n2", | ||
- | "symbol": 1 | ||
- | } | ||
- | ], | ||
- | "line": 4, | ||
- | "symbol": 1 | ||
- | } | ||
- | }, | ||
- | "types": {}, | ||
- | "type": "Statements" | ||
- | } | ||
- | </code> | ||
- | |||
===== Vérification des types dans l'AST ===== | ===== Vérification des types dans l'AST ===== | ||
Line 223: | Line 169: | ||
<code javascript> | <code javascript> | ||
{ | { | ||
- | "id": "Expression", | + | "@class" : "org.easycompiler.ast.BinaryExpression", |
- | "op": "+", | + | "errors" : [ "java.util.ArrayList", [ ] ], |
- | "left": { | + | "line" : 5, |
- | "id": "Value", | + | "typeName" : "integer", |
- | "type": "integer", | + | "left" : { |
- | "value": 2, | + | "@class" : "org.easycompiler.ast.Value", |
- | "line": 5, | + | "errors" : [ "java.util.ArrayList", [ ] ], |
- | "symbol": 0 | + | "line" : 5, |
- | }, | + | "typeName" : "integer", |
- | "right": { | + | "value" : "2" |
- | "id": "FunctionCall", | + | }, |
- | "function_name": "number", | + | "right" : { |
- | "parameters": [], | + | "@class" : "org.easycompiler.ast.FunctionCall", |
- | "line": 5, | + | "errors" : [ "java.util.ArrayList", [ ] ], |
- | "symbol": 0, | + | "line" : 5, |
- | "type": "integer" | + | "typeName" : "integer", |
- | }, | + | "function_name" : { |
- | "line": 5, | + | "@class" : "org.easycompiler.ast.Identifier", |
- | "symbol": 0, | + | "errors" : [ "java.util.ArrayList", [ ] ], |
- | "type": "integer" | + | "line" : 5, |
- | } | + | "typeName" : "number", |
+ | "title" : "number" | ||
+ | }, | ||
+ | "arguments" : [ "java.util.ArrayList", [ ] ] | ||
+ | }, | ||
+ | "op" : "ADD" | ||
+ | } | ||
</code> | </code> | ||
Line 265: | Line 217: | ||
===== Liste d'erreurs ===== | ===== Liste d'erreurs ===== | ||
- | La liste d'erreurs est un tableau qui contient des objets d'erreur. L'ordre dans lequel ces erreurs figurent dans la liste vous appartient. | + | La liste d'erreurs est une liste contient des objets d'erreur avec le type d'erreur. L'ordre dans lequel ces erreurs figurent dans la liste vous appartient. |
- | ==== Format d'objet d'erreur ==== | + | Pour les types des erreurs s'il vous plait verifie l'enum **SemanticError.Type** |
- | + | ||
- | Chaque erreur a le format suivant: | + | |
- | <code javascript> | + | |
- | { | + | |
- | type: // string with the error type | + | |
- | line: // the line number in the source (starting at 1) | + | |
- | elements: // items for the error, each type of error has different items | + | |
- | text: // the error text message | + | |
- | } | + | |
- | </code> | + | |
- | ==== Type d'erreur ==== | + | |
- | + | ||
- | Le type d'erreur est une chaîne avec l'un des titres suivants | + | |
- | + | ||
- | === VARIABLE_ALREADY_DEFINED === | + | |
- | L'erreur se produit lorsqu'une définition de variable est répétée. | + | |
- | + | ||
- | == Eléments == | + | |
- | <code javascript> | + | |
- | { | + | |
- | "type": "VARIABLE_ALREADY_DEFINED", | + | |
- | "line": 5, | + | |
- | "elements": { | + | |
- | "variable": "var_name" | + | |
- | }, | + | |
- | "text": "variable var_name is already defined" | + | |
- | } | + | |
- | </code> | + | |
- | + | ||
- | === FUNCTION_ALREADY_DEFINED === | + | |
- | L'erreur se produit lorsqu'une définition de fonction est répétée. | + | |
- | + | ||
- | == Eléments == | + | |
- | <code javascript> | + | |
- | { | + | |
- | "type": "FUNCTION_ALREADY_DEFINED", | + | |
- | "line": 5, | + | |
- | "elements": { | + | |
- | "variable": "function_name" | + | |
- | }, | + | |
- | "text": "Function function_name is already defined" | + | |
- | } | + | |
- | </code> | + | |
- | + | ||
- | === TYPE_ALREADY_DEFINED === | + | |
- | L'erreur se produit lors de la répétition d'une définition de type (tableau ou struct). | + | |
- | + | ||
- | == Eléments == | + | |
- | <code javascript> | + | |
- | { | + | |
- | "type": "TYPE_ALREADY_DEFINED", | + | |
- | "elements": { | + | |
- | "type": "s" | + | |
- | }, | + | |
- | "text": "type s is already defined" | + | |
- | } | + | |
- | </code> | + | |
- | + | ||
- | === CLASS_PROPERTY_ALREADY_DEFINED === | + | |
- | L'erreur se produit lorsqu'une définition d'élément class est répétée. | + | |
- | + | ||
- | == Eléments == | + | |
- | <code javascript> | + | |
- | { | + | |
- | "type": "CLASS_PROPERTY_ALREADY_DEFINED", | + | |
- | "line": 5, | + | |
- | "elements": { | + | |
- | "struct": "s" // class_name | + | |
- | }, | + | |
- | "text": "struct's class_name element title is already defined" | + | |
- | + | ||
- | } | + | |
- | </code> | + | |
- | + | ||
- | === ARRAY_INDEX_VALUE === | + | |
- | L'erreur se produit lorsque l'index inférieur du tableau est supérieur à l'index supérieur | + | |
- | + | ||
- | == Eléments == | + | |
- | <code javascript> | + | |
- | { | + | |
- | "type": "ARRAY_INDEX_VALUE", | + | |
- | "line": 3, | + | |
- | "elements": { | + | |
- | "array": "array_name", | + | |
- | "low_index": "low_index_value", | + | |
- | "high_index": "high_index_value" | + | |
- | }, | + | |
- | "text": "Array index lower value (low_index_value) must be smaller that the upper value (high_index_value)" | + | |
- | } | + | |
- | </code> | + | |
- | + | ||
- | === TYPE_RESOLUTION === | + | |
- | L'erreur se produit lorsque le type d'une variable n'est pas déterminable (bonus uniquement). | + | |
- | + | ||
- | == Eléments == | + | |
- | <code javascript> | + | |
- | // variable | + | |
- | { | + | |
- | variable: // le nom de la variable avec le type non résolu | + | |
- | } | + | |
- | // struct property | + | |
- | { | + | |
- | struct: // nom du type de structure | + | |
- | property: // nom de l'élément struct avec le type non résolu | + | |
- | } | + | |
- | + | ||
- | </code> | + | |
- | + | ||
- | === UNDEFINED_FUNCTION === | + | |
- | L'erreur se produit lorsqu'un appel de fonction est effectué pour une fonction qui n'est pas définie. | + | |
- | + | ||
- | == Eléments == | + | |
- | <code javascript> | + | |
- | { | + | |
- | "type": "UNDEFINED_FUNCTION", | + | |
- | "line": 2, | + | |
- | "elements": { | + | |
- | "id": "function_name" | + | |
- | }, | + | |
- | "text": "Undefined function function_name" | + | |
- | } | + | |
- | </code> | + | |
- | + | ||
- | === UNDEFINED_VARIABLE === | + | |
- | L'erreur se produit lorsqu'une variable non définie est utilisée. | + | |
- | + | ||
- | == Eléments == | + | |
- | <code javascript> | + | |
- | { | + | |
- | "type": "UNDEFINED_VARIABLE", | + | |
- | "line": 3, | + | |
- | "elements": { | + | |
- | "variable": "var_name" | + | |
- | }, | + | |
- | "text": "Undefined variable var_name" | + | |
- | } | + | |
- | </code> | + | |
- | + | ||
- | === UNDEFINED_TYPE === | + | |
- | L'erreur se produit lorsqu'un type qui n'est pas défini est utilisé. | + | |
- | + | ||
- | == Eléments == | + | |
- | { | + | |
- | "type": "UNDEFINED_TYPE", | + | |
- | "line": 3, | + | |
- | "elements": { | + | |
- | "variable": "type_name" | + | |
- | }, | + | |
- | "text": "Undefined type type_name" | + | |
- | } | + | |
- | + | ||
- | + | ||
- | === NOT_STRUCT === | + | |
- | L'erreur se produit lorsqu'une propriété est demandée pour une variable qui n'est pas un type de classe | + | |
- | + | ||
- | == Eléments == | + | |
- | <code javascript> | + | |
- | { | + | |
- | "type": "NOT_STRUCT", | + | |
- | "line": 13, | + | |
- | "elements": { | + | |
- | "type": "var_name" | + | |
- | }, | + | |
- | "text": "var_name is not a struct" | + | |
- | } | + | |
- | + | ||
- | </code> | + | |
- | + | ||
- | === NOT_ARRAY === | + | |
- | L'erreur se produit lorsqu'un index est demandé pour une variable qui n'est pas un tableau | + | |
- | + | ||
- | == Eléments == | + | |
- | <code javascript> | + | |
- | { | + | |
- | "type": "NOT_ARRAY", | + | |
- | "line": 5, | + | |
- | "elements": { | + | |
- | "type": "var_name" | + | |
- | }, | + | |
- | "text": "var_name is not an array" | + | |
- | } | + | |
- | </code> | + | |
- | + | ||
- | === ARRAY_INDEX_TYPE === | + | |
- | L'erreur se produit lorsqu'un index pour un tableau n'est pas un nombre ou un symbole | + | |
- | + | ||
- | == Eléments == | + | |
- | <code javascript> | + | |
- | { | + | |
- | "type": "ARRAY_INDEX_TYPE", | + | |
- | "line": 7, | + | |
- | "elements": { | + | |
- | "array": "array_name", | + | |
- | "index": "string" | + | |
- | }, | + | |
- | "text": "Array (array_name) index must be integer or symbol" | + | |
- | } | + | |
- | </code> | + | |
- | + | ||
- | === RETURN_OUTSIDE_FUNCTION === | + | |
- | L'erreur se produit lorsqu'une instruction de valeur (noeud de retour) est utilisée en dehors d'un message | + | |
- | + | ||
- | == Eléments == | + | |
- | <code javascript> | + | |
- | { | + | |
- | "type": "RETURN_OUTSIDE_FUNCTION", | + | |
- | "line": 3, | + | |
- | "elements": {}, | + | |
- | "text": "value is used out of function" | + | |
- | } | + | |
- | </code> | + | |
- | + | ||
- | === TYPE_EXPRESSION === | + | |
- | L'erreur se produit lorsqu'une expression a des types incompatibles | + | |
- | + | ||
- | == Eléments == | + | |
- | <code javascript> | + | |
- | { | + | |
- | "type": "TYPE_EXPRESSION", | + | |
- | "line": 6, | + | |
- | "elements": { | + | |
- | "op": "=", | + | |
- | "to": "to_type", | + | |
- | "from": "from_type" | + | |
- | }, | + | |
- | "text": "Type expression error to_type is from_type" | + | |
- | } | + | |
- | </code> | + | |
===== Bonus ===== | ===== Bonus ===== | ||
Line 512: | Line 236: | ||
===== Questions ===== | ===== Questions ===== | ||
- | Si vous avez des questions concernant les devoirs, posez-les en postant un problème sur le github [[https://github.com/alexandruradovici/alf2018.git|repository]] avec le format de titre // [semantic] <votre titre de la question> //. Vous aurez besoin d'un compte github pour cela. | + | Si vous avez des questions concernant les devoirs, posez-les en postant un problème sur le github [[https://github.com/UPB-FILS-ALF/questions|repository]] avec le format de titre // [semantic] <votre titre de la question> //. Vous aurez besoin d'un compte github pour cela. |
<note warning> | <note warning> | ||
Line 518: | Line 242: | ||
</note> | </note> | ||
- | Si vous souhaitez recevoir un e-mail lorsque des problèmes sont signalés ou lorsqu'il y a de nouveaux messages, accédez au site github [[https://github.com/alexandruradovici/alf2018|repository]] et cliquez sur // Watch //. | + | Si vous souhaitez recevoir un e-mail lorsque des problèmes sont signalés ou lorsqu'il y a de nouveaux messages, accédez au site github [[https://github.com/UPB-FILS-ALF/questions|repository]] et cliquez sur // Watch //. |