This is an old revision of the document!
L'objectif du devoir est de créer la table de symboles et d'écrire l'analyse sémantique pour le langage Alf.
Vous recevrez comme entrée un fichier qui contient un AST qui analyse correctement un langage source. Ce que vous devez faire est de générer:
Le programme recevra deux paramètres de la ligne de commande:
java ... com.example.Main source.alf.ast.json source.alf.json
Le format du fichier de sortie est le suivant
{ symbol_table: [...], // la table de symboles ast: [...], // le nouvel AST error_list: [] // la liste des erreurs }
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:
"symbolTable" : { "@class" : "org.easycompiler.semantic.SymbolTable", "errors" : [ "java.util.ArrayList", [ ] ], "variables" : { "@class" : "java.util.HashMap" }, "types" : { "@class" : "java.util.HashMap" }, "functions" : { "@class" : "java.util.HashMap", "_sum" : { "@class" : "org.easycompiler.type.Function", "errors" : [ "java.util.ArrayList", [ ] ], "title" : null, "symbolTable" : { "@class" : "org.easycompiler.semantic.SymbolTable", "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" } }, "functions" : { "@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" } } } }
Les objets de contexte stockent les suivantes propriétés:
Pour chacun des noeuds suivants, déterminez le type de retour
Définissez le type en ajoutant une propriété type dans le noeud.
"@class" : "org.easycompiler.ast.BinaryExpression", "errors" : [ "java.util.ArrayList", [ ] ], "line" : 5, "typeName" : "integer", "left" : { "@class" : "org.easycompiler.ast.Value", "errors" : [ "java.util.ArrayList", [ ] ], "line" : 5, "typeName" : "integer", "value" : "2" }, "right" : { "@class" : "org.easycompiler.ast.FunctionCall", "errors" : [ "java.util.ArrayList", [ ] ], "line" : 5, "typeName" : "integer", "function_name" : { "@class" : "org.easycompiler.ast.Identifier", "errors" : [ "java.util.ArrayList", [ ] ], "line" : 5, "typeName" : null, "title" : "number" }, "arguments" : [ "java.util.ArrayList", [ ] ] }, "op" : "ADD" }
Pour tous les noeuds AST, vérifiez que les types correspondent:
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.
Chaque erreur a le format suivant:
{ 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 }
Le type d'erreur est une chaîne avec l'un des titres suivants
L'erreur se produit lorsqu'une définition de variable est répétée.
{ "type": "VARIABLE_ALREADY_DEFINED", "line": 5, "elements": { "variable": "var_name" }, "text": "variable var_name is already defined" }
L'erreur se produit lorsqu'une définition de fonction est répétée.
{ "type": "FUNCTION_ALREADY_DEFINED", "line": 5, "elements": { "variable": "function_name" }, "text": "Function function_name is already defined" }
L'erreur se produit lors de la répétition d'une définition de type (tableau ou struct).
{ "type": "TYPE_ALREADY_DEFINED", "elements": { "type": "s" }, "text": "type s is already defined" }
L'erreur se produit lorsqu'une définition d'élément class est répétée.
{ "type": "CLASS_PROPERTY_ALREADY_DEFINED", "line": 5, "elements": { "struct": "s" // class_name }, "text": "struct's class_name element title is already defined" }
L'erreur se produit lorsque l'index inférieur du tableau est supérieur à l'index supérieur
{ "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)" }
L'erreur se produit lorsque le type d'une variable n'est pas déterminable (bonus uniquement).
// 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 }
L'erreur se produit lorsqu'un appel de fonction est effectué pour une fonction qui n'est pas définie.
{ "type": "UNDEFINED_FUNCTION", "line": 2, "elements": { "id": "function_name" }, "text": "Undefined function function_name" }
L'erreur se produit lorsqu'une variable non définie est utilisée.
{ "type": "UNDEFINED_VARIABLE", "line": 3, "elements": { "variable": "var_name" }, "text": "Undefined variable var_name" }
L'erreur se produit lorsqu'un type qui n'est pas défini est utilisé.
{
"type": "UNDEFINED_TYPE", "line": 3, "elements": { "variable": "type_name" }, "text": "Undefined type type_name"
}
L'erreur se produit lorsqu'une propriété est demandée pour une variable qui n'est pas un type de classe
{ "type": "NOT_STRUCT", "line": 13, "elements": { "type": "var_name" }, "text": "var_name is not a struct" }
L'erreur se produit lorsqu'un index est demandé pour une variable qui n'est pas un tableau
{ "type": "NOT_ARRAY", "line": 5, "elements": { "type": "var_name" }, "text": "var_name is not an array" }
L'erreur se produit lorsqu'un index pour un tableau n'est pas un nombre ou un symbole
{ "type": "ARRAY_INDEX_TYPE", "line": 7, "elements": { "array": "array_name", "index": "string" }, "text": "Array (array_name) index must be integer or symbol" }
L'erreur se produit lorsqu'une instruction de valeur (noeud de retour) est utilisée en dehors d'un message
{ "type": "RETURN_OUTSIDE_FUNCTION", "line": 3, "elements": {}, "text": "value is used out of function" }
L'erreur se produit lorsqu'une expression a des types incompatibles
{ "type": "TYPE_EXPRESSION", "line": 6, "elements": { "op": "=", "to": "to_type", "from": "from_type" }, "text": "Type expression error to_type is from_type" }
Pour un 0.5p supplémentaire, trouver le type de variables qui sont déclarées en utilisant juste une attribution.
Le devoir est individuel. Toute tentative de copiage entraînera 0p pour les devoirs. Système anti-copiage automatisé sera utilisé.
Si vous avez des questions concernant les devoirs, posez-les en postant un problème sur le github repository avec le format de titre [semantic] <votre titre de la question> . Vous aurez besoin d'un compte github pour cela.
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 repository et cliquez sur Watch .