Analyse lexicale Analyse syntaxique Évaluation



Documents pareils
Chap 4: Analyse syntaxique. Prof. M.D. RAHMANI Compilation SMI- S5 2013/14 1

Machines virtuelles fonctionnelles (suite) Compilation ML Java

Ingénierie Dirigée par les Modèles. Editeurs de modèles. (Eclipse Modeling Tools) Jean-Philippe Babau

INF2015 Développement de logiciels dans un environnement Agile. Examen intra 20 février :30 à 20:30

TP 1. Prise en main du langage Python

Programmer en JAVA. par Tama

Interpréteur d algèbre relationnelle

Java Licence Professionnelle CISII,

Introduction au langage C

Compilation. Algorithmes d'analyse syntaxique

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

Algorithmique et Programmation, IMA

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Corrigé des exercices sur les références

Théorie de la Programmation

SHERLOCK 7. Version du 01/09/09 JAVASCRIPT 1.5

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

Cours 14 Les fichiers

Programmation en Java IUT GEII (MC-II1) 1

Programmation Orientée Objet Java

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Programmation Web. Madalina Croitoru IUT Montpellier

Plan. Exemple: Application bancaire. Introduction. OCL Object Constraint Language Le langage de contraintes d'uml

Définition des Webservices Ordre de paiement par . Version 1.0

Cours 1 : La compilation

Projet de programmation (IK3) : TP n 1 Correction

TD Objets distribués n 3 : Windows XP et Visual Studio.NET. Introduction à.net Remoting

Rappel. Analyse de Données Structurées - Cours 12. Un langage avec des déclaration locales. Exemple d'un programme

I. Introduction aux fonctions : les fonctions standards

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

Traduction des Langages : Le Compilateur Micro Java

Programmation par les Objets en Java

as Architecture des Systèmes d Information


CH.6 Propriétés des langages non contextuels

LES OUTILS D ALIMENTATION DU REFERENTIEL DE DB-MAIN

Auto-évaluation Programmation en Java

Présentation du langage et premières fonctions

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

Threads. Threads. USTL routier 1

Java Licence Professionnelle CISII,

Cours d introduction à l informatique. Partie 2 : Comment écrire un algorithme? Qu est-ce qu une variable? Expressions et instructions

Notions fondamentales du langage C# Version 1.0

OpenPaaS Le réseau social d'entreprise

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Projet de Veille Technologique

Plan du cours. Historique du langage Nouveautés de Java 7

Introduction à la programmation Travaux pratiques: séance d introduction INFO0201-1

Un ordonnanceur stupide

Cours de Programmation 2

Modernisation, développement d applications et DB2 sous IBM i Technologies, outils et nouveautés Volubis.fr

Exclusion Mutuelle. Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr. Université de Provence. 9 février 2011

Une introduction à Java

Chapitre 2 Devine mon nombre!

Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie

SQL Parser XML Xquery : Approche de détection des injections SQL

Plateforme PAYZEN. Définition de Web-services

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Classes et Objets en Ocaml.

Cours 1 : Introduction. Langages objets. but du module. contrôle des connaissances. Pourquoi Java? présentation du module. Présentation de Java

Perl Console. Votre compagnon pour développer en Perl. Les Journées du Perl , 17 novembre, Lyon. Alexis Sukrieh

Cette application développée en C# va récupérer un certain nombre d informations en ligne fournies par la ville de Paris :

Utilisation d objets : String et ArrayList

Introduction à la programmation concurrente

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

Développement mobile MIDP 2.0 Mobile 3D Graphics API (M3G) JSR 184. Frédéric BERTIN

TD3: tableaux avancées, première classe et chaînes

Conventions d écriture et outils de mise au point

Lambda! Rémi Forax Univ Paris-Est Marne-la-Vallée

TP1 : Initiation à Java et Eclipse

OCL - Object Constraint Language

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

Bernard HAMM, Évelyne LAVOISIER

STAGE IREM 0- Premiers pas en Python

Générer un analyseur avec Flex&Bison

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

Vérification formelle de la plate-forme Java Card

Introduction à JDBC. Accès aux bases de données en Java

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu.

UEO11 COURS/TD 1. nombres entiers et réels codés en mémoire centrale. Caractères alphabétiques et caractères spéciaux.

Théorie des Langages

Langage Java. Classe de première SI

Recherche dans un tableau

TP3 : Manipulation et implantation de systèmes de fichiers 1

Programmation Par Objets

length : A N add : Z Z Z (n 1, n 2 ) n 1 + n 2

Tp 1 correction. Structures de données (IF2)

Surveillance de Scripts LUA et de réception d EVENT. avec LoriotPro Extended & Broadcast Edition

Introduction à l algorithmique et à la programmation M1102 CM n 3

INITIATION AU LANGAGE JAVA

4. Groupement d objets

ACTIVITÉ DE PROGRAMMATION

RAPPELS SUR LES METHODES HERITEES DE LA CLASSE RACINE Object ET LEUR SPECIALISATION (i.e. REDEFINITION)

Gestion mémoire et Représentation intermédiaire

Transcription:

Analyse lexicale Analyse syntaxique Évaluation Génération de code - Cours 1 {Remi.Forax, Matthieu.Constant, Michel.Chilowicz}@univ-mlv.fr Tatoo nain d'argentine ( Cliff1066, CC-By)

Génération de code Objectifs principaux Comprendre le fonctionnement interne d'un compilateur et donc d'un programme Écrire un compilateur Utilisation du compilateur de compilateur Tatoo Séances : Un cours d'introduction (celui-ci) Des TPs d'introduction à Tatoo et de suivi de projet Génération de code - cours 1 2

Plan de cette séance Introduction : la compilation Contenu des cours et des travaux pratiques Analyse lexicale avec Tatoo (expressions rationnelles) Analyse syntaxique avec Tatoo (grammaire, analyse LR, priorité) Analyseur combinant analyses lexical et syntaxique Evaluation d'expressions booléennes avec une pile Génération de code - cours 1 3

Un compilateur Un compilateur est un programme qui prend une description en entrée et la transforme en programme en sortie Un compilateur est un générateur de programmes Génération de code - cours 1 4

Etapes de la compilation Analyse lexicale (transforme un fichier en une séquence de lexèmes à l'aide d'un lexique) Analyse syntaxique (transforme une suite de lexèmes en arbre AST à l'aide d'une grammaire) Analyse sémantique (vérification du typage, optimisation...) Génération de code (transformation de l'ast en code exécutable) Génération de code - cours 1 5

Etapes de la compilation Analyse lexicale let x = 2 + 3 let x = 2 + 3 Analyse syntaxique Let = Let = x + Vérification du typage x int + int 2 3 2 3 int int Génération de code - cours 1 6

Etapes de la compilation Let = Let = x int + int Optimisation x 5 int int Génération de code iconst 5 istore 0 2 3 int int Génération de code - cours 1 7

Quelques générateurs de compilateurs Génération de compilateurs en langage C : (F)lex pour l'analyse lexicale Yacc, Bison pour l'analyse syntaxique Génération de compilateurs en Java : JavaCC(LL) : compilateur historique de Sun ANTLR(LL) : assez populaire Jflex/JCup(LALR) : syntaxe proche de Flex/Yacc SableCC(LR) : génération d'asts Génération de code - cours 1 8

Tatoo Générateur d'analyseurs lexical et syntaxique, développé au LIGM (R. Forax, J. Cervelle et G. Roussel) Utilisé en IR depuis ~5 ans et depuis plus longtemps en recherche Quelques caractéristiques : Écrit en Java Séparation propre entre le lexique et la grammaire Construction automatique de l'ast Génération de code - cours 1 9

Techniques utilisées Analyse lexicale Analyse syntaxique Analyse sémantique Génération de code Expressions rationnelles Grammaires analyse LR Analyse procédurale - visiteur Analyse procédurale - visiteur Génération de code - cours 1 10

Tatoo - principe Les expressions rationnelles et la grammaire sont définies dans un fichier EBNF. EBNF : Extended Backus Naur Form Extended : support aisé des répétitions (*, +) Tatoo génère automatiquement à partir de la spécification EBNF les classes Java implantant l'analyseur lexical et l'analyseur syntaxique correspondant. Il faut implanter en Java l'analyseur en combinant ces classes. Génération de code - cours 1 11

Analyse lexicale ou tokenisation L'analyseur lexical (ou lexer) transforme un fichier en une séquence de lexèmes (tokens) à l'aide d'un ensemble d'expressions rationnelles (transformées en automates) Un token contient deux informations : la catégorie du token sa valeur (la chaîne de caractères correspondante) Génération de code - cours 1 12

Analyse lexicale ou tokenisation Simplifie l'écriture de la grammaire L'analyseur lexical supprime Les espaces Les commentaires Les retours à la ligne (suivant le language),... Génération de code - cours 1 13

Tokenisation Pour chaque token, l'automate qui a reconnu le motif fournit une catégorie (kind) et sa valeur (value) kind: let value: let kind: = value: = kind: + value: + let x = 2 + 3 let x = 2 + 3 kind: identifier value: x kind: number value: 2 kind: number value: 3 Génération de code - cours 1 14

Catégories Les catégories les plus fréquentes : mots-clés du langage (types primitifs, introduction de structures, contrôle de flux...) symboles de ponctuation (séparation d'arguments, de lignes) opérateurs littéraux (valeurs entières, réelles,, chaînes de caractères) Identificateurs (noms des types, des variables, des fonctions,...) Génération de code - cours 1 15

Tokenisation avec Tatoo Configuration dans un fichier.ebnf kind tokens: let = 'let' assign = '=' plus = '\+' identifier = '[A-Za-z]+' number = '[0-9]+' expression rationnelle (regex) kind: let value: let kind: assign value: = kind: plus value: + let x = 2 + 3 let x = 2 + 3 kind: identifier value: x kind: number value: 2 kind: number value: 3 Génération de code - cours 1 16

Format des expressions rationnelles de Tatoo foo f suivi de o suivi de o (concaténation) [a-z] lettre entre a et z [^a] toute les lettres sauf a (complément). n'importe quel caractère a b a ou b a? a ou ε a* a répété 0 à n fois a+ a répété 1 à n fois \ le caractère ' ' (déspécialisation avec \) Génération de code - cours 1 17

Exemples d'expressions rationnelles Mots-clés : 'if', 'for', 'return' Opérateurs : '\+', '-', '\*' Entiers : '[0-9]+ (0x[0-9A-Fa-f]+)' Caractères : "'[^']'" Chaîne de caractères : '"[^"]*"' Identificateurs : [A-Za-z_][0-9A-Za-z_]* Génération de code - cours 1 18

Procédure de tokenisation Application glissante L'analyseur lexical lance la reconnaissance sur tous les automates en parallèle En cas d'ambiguïtés entre plusieurs automates On prend celui qui reconnaît le + long motif Si 2 automates reconnaissent le même motif, on prend celui qui est déclaré en premier dans l'ordre du fichier EBNF Génération de code - cours 1 19

Tatoo a différents types de tokens Les tokens (tokens:) qui correspondent à des mots-clés Les blancs (blanks:) qui sont des espaces qui ne seront pas pris en compte Les commentaires (comments:) qui ne seront pas pris en compte par l'analyseur syntaxique Génération de code - cours 1 20

Exemple Attention, les sections doivent être déclarées dans cet ordre tokens: id = [A-Za-z]([0-9A-Za-z])* blanks: space= "( \t \r \n)+" comments: comment="#([^\r\n])*(\r)?\n" Génération de code - cours 1 21

Tokenisation - exemple l e t x = 2 + 3 let value kind l e t x = 2 + 3 let l e t x = 2 + 3 let x l e t x = 2 + 3 let x = Génération de code - cours 1 22

Tokenisation exemple (suite) l e t x = 2 + 3 let x = 2 l e t x = 2 + 3 let x = 2 + l e t x = 2 + 3 let x = 2 + 3 Génération de code - cours 1 23

Fonctionnement du lexer de Tatoo LexerDataTable (classe java) Lit le fichier à analyser Reader utilise RuleEnum (classe java) Génère Avec Ant Fichier.ebnf Lexer ruleverified() LexerListener remplit TokenBuffer view(), discard() view() renvoie le texte du token discard() indique que les données du buffer ont été lues Génération de code - cours 1 24

Génération des classes de base du lexer à l'aide de ANT et Tatoo <?xml version="1.0"?> <project name="eval" default="all" basedir="."> <property name="tatoo-build.dir" location="../build-lib"/> <property name="tatoo.jar" location="${tatoo-build.dir}/tatoo.jar"/> <property name="gen-src" value="gen-src"/> <property name="ebnf.file" value="file.ebnf"/> <property name="lexer.package" value="fr.umlv.compil.file.lexer"/> <target name="tasks"> <taskdef name="ebnf" classname="fr.umlv.tatoo.cc.ebnf.main.ebnftask" classpath="${tatoo.jar}"/> </target> <target name="ebnf" depends="tasks"> <delete dir="${gen-src}"/> <ebnf destination="${gen-src}" ebnffile="${ebnf.file}" parsertype="lalr"> <package lexer="${lexer.package}"/> </ebnf> </target> Génération de code - cours 1 25

Implémentation du lexer Reader reader =... LexerListener<RuleEnum, TokenBuffer<CharSequence>> lexerlistener = new LexerListener<RuleEnum, TokenBuffer<CharSequence>>() { @Override public void ruleverified(ruleenum rule, int tokenlength, TokenBuffer<CharSequence> buffer) { System.out.println("recognize token: "+rule+" "+buffer.view()); buffer.discard(); } }; SimpleLexer lexer = Builder.lexer(LexerDataTable.createTable()). reader(reader). listener(lexerlistener). create(); lexer.run(); Génération de code - cours 1 26

Buffer de Tatoo Tatoo utilise une interface LexerBuffer pour discuter avec les flux de caractères en entrée Cette interface permet de ne pas avoir le contenu total d'un fichier pour effectuer l'analyse lexicale. Seule la partie nécessaire à l'analyse lexicale réside dans un buffer qui s'agrandit automatiquement si nécessaire Génération de code - cours 1 27

Buffer de Tatoo Le ReaderWrapper est le buffer qui lit des données à partir d'un java.io.reader Reader reader =... LexerBuffer buffer = new ReaderWrapper(reader, null); LexerListener<RuleEnum, TokenBuffer<CharSequence>> lexerlistener =...; SimpleLexer lexer = Builder.lexer(LexerDataTable.createTable()). buffer(buffer). listener(lexerlistener). create(); lexer.run(); Génération de code - cours 1 28

Numéro de ligne/colonne Un LocationTracker permet de connaître les numéros de ligne/colonne actuelles Reader reader =... LocationTracker tracker = new LocationTracker(); LexerBuffer buffer = new ReaderWrapper(reader, tracker); LexerListener<RuleEnum, TokenBuffer<CharSequence>> lexerlistener =...; SimpleLexer lexer = Builder.lexer(LexerDataTable.createTable()). buffer(buffer). listener(lexerlistener). create(); try { lexer.run(); } catch(lexingexception e) { System.out.println("erreur à la ligne " + tracker.getlinenumber()); } Génération de code - cours 1 29

Analyse syntaxique Le but est de vérifier qu'un flux de tokens respecte une grammaire algébrique en parcourant l'arbre syntaxique Il existe plusieurs algorithmes, LL, LR, SLR, LALR. Tatoo est un analyseur LR et nous utiliserons LALR. Génération de code - cours 1 30

Analyse syntaxique A partir d'une grammaire, l'analyse LR produit un automate d'items (i.e. une table d'analyse) A partir de cette table, tout flux de tokens est converti en une suite d'opérations : décalage (shift), réduction (reduce) ou reconnaissance (accept) La suite d' opérations est alors transformée en arbre (réel ou d'appels de méthodes) Génération de code - cours 1 31

Analyse syntaxique start let x = true && false instr x && true false Génération de code - cours 1 32

Grammaire Une grammaire est définie par un ensemble de productions Chaque production est de la forme NonTerminal = (Terminal NonTerminal)* Un terminal correspond à la catégorie d'un token productions: expr = 'value' expr 'plus' expr ; Terminal (entre ' ') Non-terminal (sans '') Génération de code - cours 1 33

Grammaire Avec Tatoo, elle est spécifiée dans le fichier EBNF 'bar' est un terminal et baz est un non-terminal Avec foo un terminal ou un non terminal foo? Indique une répétition 0 à 1 fois foo* indique une répétition 0 à n fois foo+ indique une répétition 1 à n fois foo/bar* indique 0..n foo séparés par des bar foo/bar+ indique 1..n foo séparés par des bar Génération de code - cours 1 34

Grammaire dans le fichier ebnf starts: indique le(s) non-terminal(aux) de départ productions: indique l'ensemble des productions Génération de code - cours 1 35

Exemple de fichier ebnf tokens: _true='true' _false='false' let='let' and='&&' id='[a-za-z]+' starts: start productions: start = instr* ; instr = 'let' 'id' 'assign' expr ; expr = '_true' '_false' expr 'and' expr ; Génération de code - cours 1 36

Astuces avec Tatoo Les terminaux et non-terminaux utilisés par Tatoo doivent être des identificateurs valides en Java (donc pas le droit à if, else, true, etc.) La directive autoalias permet d'utiliser l'expression rationnelle comme alias pour un terminal directives: autoalias tokens: plus = '\+' productions: expr = expr '+' expr ; On peut alors utiliser '+' à la place de 'plus' Génération de code - cours 1 37

Productions nommées Avec Tatoo, les productions sont nommées (entre accolades) Si un non-terminal n'a qu'une production, la production peut avoir le même nom que le non-terminal productions: start = instr* { start } ; instr = 'let' 'id' '=' expr { instr } ; expr = 'true' { expr_true } 'false' { expr_false } expr '&&' expr { expr_and } ; Génération de code - cours 1 38

Analyse syntaxique avec productions nommées productions: start = instr* { start } ; instr = 'let' 'id' '=' expr { instr } ; expr = 'true' { expr_true } 'false' { expr_false } expr '&&' expr { expr_and } ; start instr let x = true && false analyse id expr_and expr_true expr_false Génération de code - cours 1 39

Analyse syntaxique et ambiguïté S'il y a deux arbres de dérivation possibles, la grammaire est ambiguë expr = 'true' { expr_true } 'false' { expr_false } expr '&&' expr { expr_and } ; Exemple : let x = true && false && false Solution 1 expr_and Solution 2 expr_and expr_true expr_and expr_and expr_false expr_false expr_false expr_true expr_false Génération de code - cours 1 40

Analyse syntaxique et ambiguïté L'analyse LR détecte les ambiguïtés Avec Tatoo: shift/reduce conflict state 9: Deux solutions: Ré-écrire la grammaire (cf. cours analyse syntaxique) Mettre des priorités Génération de code - cours 1 41

Priorité et associativité avec tatoo Lorsqu'il y a un conflit décalage/réduction, on compare les priorités : la plus grande priorité est choisie Puis on applique l'associativité parmi left ((expr && expr) && expr) right (expr && (expr && expr)) nonassoc (non associatif) Génération de code - cours 1 42

Conflit entre opérateurs expr = 'true' 'false' expr '&&' expr expr ' ' expr ; Exemple: true false && true 2 arbres possibles: (true false) && true true (false && true) Génération de code - cours 1 43

Conflit résolu par priorité '&&' est plus prioritaire que ' ' priorities: boolean_or = 1 left boolean_and = 2 left tokens: and = '&&' [boolean_and] or = '\ \ ' [boolean_or] productions: expr = 'true' 'false' expr '&&' expr [boolean_and] expr ' ' expr [boolean_or] ; Priorité donnée lors d'un décalage par && Priorité donnée lors d'une réduction par Expr = expr '&&' expr Génération de code - cours 1 44

Sortie d'un analyseur syntaxique LR start = instr* { start } ; instr = 'let' 'id' '=' expr { instr } ; expr = 'true' { expr_true } 'false' { expr_false } expr '&&' expr [boolean_and] { expr_and } ; Exemple: let x = true && false let id = true expr_true && false expr_false expr_and instr start start décalage réduction reconnaissance Génération de code - cours 1 45

L'analyseur syntaxique (Parser) de Tatoo L'automate LR est encodé dans la classe ParserDataTable. Fichier ebnf génère avec ant et tatoo ProductionlEnum (classe java) ParserDataTable (classe java) TerminalEnum (classe java) Parser shift/reduce accept ParserListener NonTerminalEnum (classe java)... Génération de code - cours 1 46

Analyse syntaxique avec Tatoo On utilise un listener pour être averti des actions effectuées par l'analyseur ParserListener<TerminalEnum, NonTerminalEnum, ProductionEnum> parserlistener = new ParserListener<TerminalEnum, NonTerminalEnum, ProductionEnum>() { public void shift(terminalenum terminal) { // shift d'un terminal } public void reduce(productionenum production) { // reduce d'une production } public void accept(nonterminalenum nonterminal) { // accept d'un non terminal } }; SimpleParser<TerminalEnum> parser = Builder.parser(ParserDataTable.createTable()). listener(parserlistener). create(); Génération de code - cours 1 47

Analyseur = Lexer + Parser On associe les règles du lexer aux terminaux du parser LexerDataTable Fichier ebnf Genère avec ant et tatoo ToolsDataTable ParserDataTable Lexer RuleEnum TerminalEnum Parser comments shift/reduce ToolsListener Génération de code - cours 1 48

Analyseur avec Tatoo Reader reader =... ToolsListener<RuleEnum, TokenBuffer<CharSequence>, TerminalEnum, NonTerminalEnum, ProductionEnum> toolslistener =...; Builder.analyzer(LexerDataTable.createTable(), ParserDataTable.createTable(), ToolsDataTable.createToolsTable()). reader(reader). listener(toolslistener). create(). run(); Génération de code - cours 1 49

Analyseur avec Tatoo ToolsListener<RuleEnum, TokenBuffer<CharSequence>, TerminalEnum, NonTerminalEnum, ProductionEnum> toolslistener = new ToolsListener<RuleEnum, TokenBuffer<CharSequence>, TerminalEnum, NonTerminalEnum, ProductionEnum>() { public void comment(ruleenum rule, TokenBuffer<CharSequence> buffer) { // commentaire } public void shift(terminalenum terminal, RuleEnum rule, TokenBuffer<CharSequence> buffer) { // shift } public void reduce(productionenum production) { // reduce } public void accept(nonterminalenum nonterminal) { // accept } }; Génération de code - cours 1 50

Évaluateur à la main Le ToolsListener permet d'écrire un évaluateur Besoin d'une pile de valeur (ici des booléens) Evaluation: On empile true ou false lors d'un shift correspondant Lors d'un reduce expr_and, on dépile deux valeurs, on effectue l'opération et on empile le résultat Lors d'un reduce de instr, on dépile la valeur et on affiche le résultat Génération de code - cours 1 51

Evaluateur à la main let id = true true let id = true expr_true && false false true let id = true expr_true && false expr_false expr_and false true && false let id = true expr_true && false expr_false expr_and instr print false Génération de code - cours 1 52

Evaluateur à la main new ToolsListener<RuleEnum, TokenBuffer<CharSequence>, TerminalEnum, NonTerminalEnum, ProductionEnum>() { public void shift(evalterminalenum terminal, EvalRuleEnum rule, TokenBuffer<CharSequence> buffer) { if (rule == EvalRuleEnum._true rule == EvalRuleEnum._false) { stack.push(boolean.parseboolean(buffer.view().tostring())); } } public void reduce(evalproductionenum production) { switch(production) { case expr_and: { boolean secondvalue = stack.pop(); boolean firstvalue = stack.pop(); stack.push(firstvalue && secondvalue); break; } case instr: System.out.println("value: "+stack.pop()); break; default: } }... }; Génération de code - cours 1 53