TP 6 - AST: Continuation

Vous devez accepter l'assignment d'ici est travailler avec ce repository: Lab 6

L'AST est une représentation arborescente de la structure syntaxique abstraite du code source écrit dans un langage de programmation. Chaque nœud de l'arborescence désigne un jeton identifié, reconnu comme étant dans un ordre correct pour le langage défini dans la grammaire.

La structure de l'AST dépend beaucoup de la complexité de la grammaire:

Le but de ce TP est de vous habituer a travailler plus avec le parser, le visiteur et la generation de l'arbre de syntaxe abstraite, en continuant le dévéloppement du TP passé.

Etant donnée la grammaire suivante:

grammar Ex1;
 
start               : (statement SEMICOLON NEWLINE*)*               #multilineProg
                    | statement SEMICOLON NEWLINE*                  #singlelineProg 
                    ;
 
statement           : declaration                                   #declarationRule
                    | expression                                    #expressionRule
                    | attribution                                   #attributionRule
                    ;
 
declaration         : type VARIABLE EQ expression                   #variableDeclaration
                    ;
 
type                : INT                                           #typeInt
                    | FLOAT                                         #typeFloat
                    | STRING                                        #typeString
                    ;
 
value               : INT_NUMBER                                    #valueInt
                    | FLOAT_NUMBER                                  #valueFloat
                    | STRING_TEXT                                   #valueString
                    | VARIABLE                                      #valueVariable
                    ;
 
expression          : left=expression op=MUL right=expression       #expressionMultiply
                    | left=expression op=DIV right=expression       #expressionDivision                   
                    | left=expression op=REM right=expression       #expressionRem 
                    | left=expression op=ADD right=expression       #expressionAddition
                    | left=expression op=SUB right=expression       #expressionSubtraction
                    | LP expression RP                              #expressionParanthesis
                    | value                                         #expressionValue
                    ;
 
/** TODO 1: Add the tokens (in the Lexer part) and the rules (with aliases) for boolean expressions
  * Operators: OR, AND, NOT
  * Values: true, false, variables 
 */
 
 
attribution         : VARIABLE EQ expression                        #variableAttribution
                    ;
 
 
/** TODO 4: Add the tokens (in the Lexer part) and the rules (with aliases) for lists declaration
  * Keyword: list
  * Name: any variable name
  * Values: any value separated by comma
 */
 
 
/** TODO 5: Add the tokens (in the Lexer part) and the rules (with aliases) for functions declaration
  * Keyword: function
  * Name: any variable name
  * Parameters: any declaration separated by comma
  * Instructions: any statement separated by a semicolon and one or more new lines
  * Return: "return" keyword + any statement ending with a semicolon 
 */
 
/** BONUS: Add the tokens (in the Lexer part) and the rules (with aliases) for function calls
  * Function name: any variable name
  * Parameters: any value separated by comma
  * Add the function call to the variable declaration  
 */
 
 
WS                  :   (' ')       -> skip;
NEWLINE             :   ([\r\n]+)   -> skip;
VARIABLE            :   ('_'[a-zA-Z0-9]+);
ADD                 :   '+';
SUB                 :   '-';
MUL                 :   '*';
DIV                 :   '/';
REM                 :   '%';
INT                 :   'int';
FLOAT               :   'float';
STRING              :   'string';
LP                  :   '(';
RP                  :   ')';
EQ                  :   '=';
SEMICOLON           :   ';';
INT_NUMBER          :   ([0-9]+);
FLOAT_NUMBER        :   ([0-9]+'.'[0-9]+);
STRING_TEXT         :   ('"'~["]+'"'|'\''~[']+'\'');

Vous pouvez aussi observer la grammaire et aussi les implementations des classes et de visiteur dans le repository Github donné pour le TP d'aujourd'hui.

Le résultat généré aura le format suivant:

{
    "id": "statements",
    "statements": [
        {
            "id": "declaration",
            "variable_type": "int",
            "variable": "_var1",
            "value": {
                "id": "expression",
                "left": {
                    "id": "expression",
                    "left": {
                        "id": "value",
                        "value": 2
                    },
                    "right": {
                        "id": "value",
                        "value": 5
                    },
                    "op": "+"
                },
                "right": {
                    "id": "expression",
                    "left": {
                        "id": "value",
                        "value": 7
                    },
                    "right": {
                        "id": "value",
                        "value": 3
                    },
                    "op": "*"
                },
                "op": "/"
            }
        }
    ]
}

Erreurs

Au niveau de l'anayse on peut retrouver 2 types d'erreurs:

  • Erreurs lexicales - le Parser trouve des jetons qu'il ne peut pas identifier dans le Lexer
  • Erreurs syntaxiques - le texte ne respecte pas les règles indiquées dans la grammaire

Pour pouvoir traiter ces erreurs, on doit tout d'abord éliminer les écouteurs d'erreurs par défaut d'ANTLR (ErrorListeners)

lexer.removeErrorListeners ();
parser.removeErrorListeners ();

Ensuite, il faut créer un nouvel outil qui puisse attraper et afficher les erreurs. Pour cela, on peut définir une nouvelle classe:

public class ErrorPrinter implements ANTLRErrorListener {
    @Override
    public void syntaxError(Recognizer<?, ?> recognizer, Object o, int i, int i1, String s, RecognitionException e) {
        if (e != null) {
            System.out.println("line: "+i+" position: "+i1+" message: "+s);
        }
    }
}

Finalament, on doit indiquer au parser et au lexer quels sont les nouveaux écouteurs:

lexer.addErrorListener (new ErrorPrinter());
parser.addErrorListener (new ErrorPrinter());

Exercices

  1. Téléchargez le repository de Github pour TP6 et utilisez la grammaire Alf.g4 comme support pour les exercices. En suivant les lignes marquées par TODO 1, ajoutez les règles de grammaire, les classes et les méthodes nécessaires pour pouvoir déclarer aussi des variables et des expressions booléennes. Testez la fonctionnalité du programme pour l'exemple suivant: (2p)
     bool _var1 = _var2 ||_var3 && !_var4; 
  2. Faites que la grammaire accepte aussi la concaténation des chaines de caracteres. Vérifiez pour l'exemple suivant: (1.5p)
     String _var2 = "FILS " + "ALF"; 
  3. En suivant les lignes marquées par TODO 4, ajoutez à la grammaire les règles, classes et méthodes nécessaires pour que vous puissiez déclarer des listes. Les listes peuvent inclure n'importe quel type de données . Vérifiez pour la déclaration suivante: (1.5p)
     list _var1 = [10, 5.5, 'alf', true, _var2]; 
  4. En suivant les lignes marquées par TODO 5, ajoutez les règles, les classes et les méthodes necessaires pour la déclaration des fonctions. Une fonction peut avoir un ou plusieurs paramètres et son contenu peut inclure une seule ou plusieurs instructions. Vérifiez la correctitude de votre programme pour l'exemple suivant: (3.5p)
    function _functionName (int _var1=0, String _var2="alf", bool _var3=true)
    {
        _var1 = _var2 + "2021";
        _var4 = false;
    
        return 3+5/7;
    };
  5. BONUS: Traitez les erreurs de lexer et de syntaxe pour votre arbre et affichez les messages nécessaires. (1.5p)
alf/laboratoare/06_fr_java.txt · Last modified: 2023/04/11 01:03 by alexandra.negoita02
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0