:: Enseignements :: ESIPE :: E4INFO :: 2008-2009 :: Compilation :: Tutoriel Tatoo ::
[LOGO]

Implanter un analyseur syntaxique couplé à un analyseur lexical


Génération des classes associées au lexeur et au parseur

La première étape consiste à décrire les règles de reconnaissance des lexèmes et la grammaire associée à l'analyseur. Cette étape est décrite dans le chapitre Description du fichier EBNF.

Vous devez ensuite générer trois packages contenant les classes Java implémentant les composants fondamentaux de l'analyseur. Le package lexer associé à l'analyseur lexical contient deux classes :
  • LexerDataTable qui permet de créer la table qui, à chaque règle associe, un automate fini qui reconnais le token.
  • RuleEnum qui est une énumération des règles.
Le package parser associé à l'analyseur syntaxique, contient cinq classes:
  • NonTerminalEnum qui est une énumération des éléments non-terminaux de la grammaire
  • ProductionEnum qui est une énumération des noms des productions de la grammaire
  • VersionEnum qui est une énumération des versions de la grammaire
  • TerminalEnum qui est une énumération des éléments terminaux
  • ParserDataTable qui est implémente l'automate à pile associé à la grammaire
Le package tools (avec l'unique classe ToolsDataTable) permet de faire la correspondance entre les tokens reconnus par le lexeur et les éléments terminaux de la grammaire du parseur.

La génération de ces trois packages peut être réalisée à l'aide d'une tâche ant. Dans l'exemple simple-parser, le fichier build.xml permet de générer ces packages dédiés à l'analyseur décrit dans simple-parser.ebnf. La tâche associée génère trois packages
  • fr.umlv.tatoo.tutorial.simpleparser.lexer
  • fr.umlv.tatoo.tutorial.simpleparser.parser
  • fr.umlv.tatoo.tutorial.simpleparser.tools
Les packages sont placés dans le répertoire de destination gen-src.

La balise ebnf du fichier de configuration contient différents attributs:
  • parserType qui définit le type du parser à générer : soit 'slr' (type SLR), soit 'lr' (LR1), soit 'lalr' (LALR).
  • ebnfFile qui indique le fichier EBNF décrivant l'analyseur
  • logFile qui indique le nom du fichier log qui contient différentes informations sur l'analyseur (ex. automate d'items, premiers, suivants)

simple-parser.ebnf


build-simple-parser.xml

Implantation

Une fois les packages dédiés à l'analyseur générés, il s'agit de créer l'analyseur en tant que tel. La classe fr.umlv.tatoo.runtime.tools.builder.Builder dans tatoo-runtime.jar contient des méthodes simples à cet effet (cf. la javadoc). Dans les faits, il s'agit de créer un lexeur couplé à un analyseur syntaxique. La création du lexeur nécessite, au minimum, de:
  • un LexerDataTable créé à partir de la méthode statique createTable() de la classe LexerDataTable générée par Tatoo.
  • un ParserDataTable créé à partir de la méthode statique createTable() de la classe ParserDataTable générée par Tatoo.
  • un ToolsDataTable créé à partir de la méthode statique createTable() de la classe ToolsDataTable générée par Tatoo.
  • un Reader lisant le texte en entrée que l'on veut compiler
  • un listeneur de type AnalyzerListener<R,B,T,N,P> indiquant les actions à réaliser à chaque étape de l'analyse syntaxique. (R est le type des règles [en général, RuleEnum], B est le type des buffers [par exemple, ReaderWrapper], T est le type des terminaux [TerminalEnum] et N est le type des productions [ProductionEnum]).
La création de l'analyseur se fait à l'aide de la méthode statique Builder.analyzer(), comme indiqué ci-dessous :
				Builder.analyzer(lexerDataTable,parserDataTable,toolsDataTable)
				.reader(reader)
				.listener(listener)
				.create()				
			
Il s'agit ensuite de récupérer le lexeur (méthode getLexer) et de le lancer à l'aide de la méthode run().

Il existe un listener de débogage qui peut être utilisé en appelant debugListener() à la place de listener(listener). Il est possible de spécifier la stratégie du lexeur en cas d'erreur en appelant la méthode defaultLexerErrorPolicy() qui prend un LexerWarningReporter<B> (B type de buffer)(cf. Javadoc).
				Builder.analyzer(lexerDataTable,parserDataTable,toolsDataTable)
				.reader(reader)
				.listener(listener)
				.expert()
				.defaultLexerErrorPolicy(lexerWarningReporter)
				.create()
			


Ci-dessous nous donnons un exemple d'implantation d'un analyseur qui reconnaît les expressions anbn.
L'AnalyzerListener implanté ne fait rien.