Parse::Token - Définition des tokens utilisés par Parse::Lex
Parse::Token
Parse::Lex
require 5.005; use Parse::Lex; @token = qw( ADDOP [-+] INTEGER [1-9][0-9]* ); $lexer = Parse::Lex->new(@token); $lexer->from(\*DATA); $content = $INTEGER->next; if ($INTEGER->status) { print "$content\n"; } $content = $ADDOP->next; if ($ADDOP->status) { print "$content\n"; } if ($INTEGER->isnext(\$content)) { print "$content\n"; } __END__ 1+2
La classe Parse::Token et ses dérivées permettent de définir les tokens utilisés par Parse::Lex ou Parse::LexEvent.
Parse::LexEvent
La création des tokens peut se faire au moyen des méthodes new() ou factory(). La méthode Lex::new() du package Parse::Lex crée indirectement des instances des tokens à reconnaître.
new()
factory()
Lex::new()
Les méthodes next() ou isnext() du package Parse::Token permettent d'interfacer l'analyseur lexical avec un analyseur syntaxique de type récursif descendant. Pour un interfaçage avec byacc voir le package Parse::YYLex.
next()
isnext()
byacc
Parse::YYLex
L'inclusion de Parse::Token se fait indirectement par un use Parse::Lex ou use Parse::LexEvent.
use Parse::Lex
use Parse::LexEvent
Retourne la fonction anonyme définie dans l'objet Parse::Token.
La méthode factory(LIST) crée et retourne une liste de tokens à partir d'une liste de spécifications incluant par token : un nom, une expression régulière et éventuellement une fonction anonyme. La liste peut inclure des objets de la classe Parse::Token ou d'une classe qui en dérive.
factory(LIST)
factory(ARRAY_REF) permet de créer des tokens à partir de spécifications de type attribut-valeur :
factory(ARRAY_REF)
Parse::Token->factory([Type => 'Simple', Name => 'EXAMPLE', Regex => '.+']);
Type indique le type de chaque token à créer (le préfixe de package n'est pas indiqué).
Type
factory() crée une série de tokens mais n'importe pas ces tokens dans le package d'appel.
On pourra pas exemple écrire :
%keywords = qw ( PROC undef FUNC undef RETURN undef IF undef ELSE undef WHILE undef PRINT undef READ undef ); @tokens = Parse::Token->factory(%keywords);
et installer ces tokens dans une table des symboles de la manière suivante :
foreach $name (keys %keywords) { ${$name} = pop @tokens; $symbol{"\L$name"} = [${$name}, '']; }
${$name} est l'instance token.
${$name}
Lors de la phase d'analyse lexicale on pourra utiliser les tokens de la manière suivante :
qw(IDENT [a-zA-Z][a-zA-Z0-9_]*), sub { $symbol{$_[1]} = [] unless defined $symbol{$_[1]}; my $type = $symbol{$_[1]}[0]; $lexer->setToken((not defined $type) ? $VAR : $type); $_[1]; # THE TOKEN TEXT }
Ce qui permet d'indiquer que tout symbole dont le type est inconnu est une variable.
Dans cet exemple nous avons utilisé $_[1] qui correspond au texte reconnu par l'expression régulière. Ce texte associé au token doit être retourné par la fonction anonyme.
$_[1]
Permet d'obtenir la valeur de l'attribut résultant de l'évaluation d'EXPR. Il est également possible d'utiliser le nom de l'attribut comme nom de méthode.
Retourne la chaîne de caractères reconnue au moyen de l'objet Parse::Token.
Synonyme de la méthode text().
text()
Retourne le statut du token. La chaîne consommée est disponible dans EXPR s'il s'agit d'une référence à un scalaire.
Retourne le nom du token.
Active la recherche du token défini par l'expression régulière contenue dans l'objet. Si ce token est reconnu sur le flot de caractère à analyser alors next() retourne la chaîne trouvée et met le statut de l'objet à vrai.
Crée un objet de type Parse::Token::Simple ou Parse::Token::Segmented. Les arguments de la méthode new() sont dans l'ordre : un nom symbolique, une expression régulière et éventuellement une fonction anonyme. Les sous-classes de Parse::Token permettent une spécification des tokens au moyen d'une liste d'attribut-valeurs.
Parse::Token::Simple
Parse::Token::Segmented
REGEXP est soit une expression régulière simple, soit une référence à un tableau contenant de une à trois expressions régulières. Dans le permier cas l'instance appartient à la classe Parse::Token::Simple Dans le second cas l'instance appartient à la classe Parse::Token::Segmented. Les tokens de ce type permettent de reconnaître des structures de type chaîne de caractères délimitée par des guillemets, des commentaires d'un programme C, etc. Les expressions régulières sont utilisées pour reconnaître :
1. le début du token,
2. le "corps" du token, si cette seconde expression est absente Parse::Lex utilise (?:.*?),
(?:.*?)
3. la fin du token, si cette dernière expression est absente on utilise la première. La fin du token ne peut être à cheval sur plusieurs enregistrements.
Exemple.
qw(STRING), [qw(" (?:[^"\\\\]+|\\\\(?:.|\n))* ")],
Les expressions régulières peuvent reconnaître des chaînes multilignes délimitées par des guillemets, sachant que le contre-oblique est utilisé pour littéraliser les guillemets qui apparaissent au sein de la chaîne. Remarquez le quadruplement du contre-oblique.
Voici une variante de l'exemple précédent qui utilise l'option s pour inclure la nouvelle-ligne dans les caractères reconnus par "." :
s
.
qw(STRING), [qw(" (?s:[^"\\\\]+|\\\\.)* ")],
(Remarques. Il est possible d'écrire des expressions régulières plus performantes en terme de temps d'exécution, mais ce n'est pas notre objectif ici, voir Mastering Regular Expressions.)
La fonction anonyme est exécutée au moment ou le token est reconnu par l'analyseur lexical. Cette fonction possède deux arguments : $_[0] contient l'instance de token, $_[1] contient la chaîne reconnue par l'expression régulière. Le scalaire retourné par la fonction anonyme définit la chaîne de caractères placée dans l'instance token.
$_[0]
Dans la fonction anonyme vous pouvez utiliser les variables positionnelles $1, $2, ... qui correspondent aux parenthèses placées dans l'expression régulière.
$1
$2
Retourne l'expression régulière définie dans l'objet Parse::Token.
Permet de décorer un token au moyen d'une liste d'attribut-valeurs.
Un nom d'attribut peut être utilisé comme nom de méthode.
La valeur de EXPR définit la chaîne de caractères associée au token.
Synonyme de la méthode text(EXPR).
text(EXPR)
Indique si la dernière recherche du token a réussie ou échouée. status EXPR permet de forcer le statut à la valeur dénotée par EXPR.
status EXPR
text() Retourne la chaîne de caractères reconnue au moyen du token. La valeur de EXPR permet de définir la chaîne de caractères associée au token.
Méthode de classe qui active/désactive une trace de l'analyse lexicale.
OUTPUT peut être un nom de fichier ou une référence à un filehandle vers laquelle la trace va être dirigée.
OUTPUT
Des sous-classes de la classe Parse::Token sont en cours de définition. Elles permettent de reconnaître des structures particulières comme, par exemple, les chaînes de caractères entre guillemets, les commentaires C, etc. Voici les sous-classes sur lesquelles je travaille actuellement :
Parse::Token::Action : permet d'insérer des expressions Perl entre deux tokens de l'analyseur lexical.
Parse::Token::Action
Parse::Token::Simple : les tokens de cette classe sont définis au moyen d'une seule expression régulière.
Parse::Token::Segmented : les tokens de cette classe sont définis au moyen de trois expressions régulières. La lecture de nouvelles données est automatique.
Parse::Token::Delimited : permet de reconnaître, par exemple, des commentaires C.
Parse::Token::Delimited
Parse::Token::Quoted : permet de reconnaître, par exemple, des chaînes de caractères entre guillemets.
Parse::Token::Quoted
Parse::Token::Nested : permet de reconnaître des structures imbriquées, telles que les expressions parenthésées. NON DéFINIE.
Parse::Token::Nested
La création de ces classes est récente et comporte sans aucun doute des bugs.
Les tokens de la classe Parse::Token::Action permettent d'insérer des expressions Perl quelconque au sein d'un analyseur lexical. Une expression peut être utilisée par exemple pour imprimer des variables internes à l'analyseur :
$LEX_BUFFER : contenu du buffer à analyser
$LEX_BUFFER
$LEX_LENGTH : longueur de la chaîne de caractères en cours d'analyse
$LEX_LENGTH
$LEX_RECORD : numéro de l'enregistrement en cours d'analyse
$LEX_RECORD
$LEX_OFFSET : nombre de caractère déjà consommés depuis le début de l'analyse
$LEX_OFFSET
$LEX_POS : position atteinte par l'analyse en nombre de caractères depuis le début du buffer.
$LEX_POS
Le constructeur de la classe accepte les attributs suivants :
Name : le nom du token
Name
Expr : une expression Perl
Expr
Exemple :
$ACTION = new Parse::Token::Action( Name => 'ACTION', Expr => q!print "LEX_POS: $LEX_POS\n" . "LEX_BUFFER: $LEX_BUFFER\n" . "LEX_LENGTH: $LEX_LENGTH\n" . "LEX_RECORD: $LEX_RECORD\n" . "LEX_OFFSET: $LEX_OFFSET\n" ;!, );
Handler : la valeur indique un nom fonction à appeler lors d'une analyse conduite par un analyseur de la classe Parse::LexEvent.
Handler
Name : la valeur associée est le nom du token.
Regex : La valeur associée est une expression régulière correspondant au motif à reconnaître.
Regex
ReadMore : si la valeur associée est 1, la reconnaissance du token se poursuit après la lecture d'un nouvel enregistrement. Les chaînes reconnues sont concaténées. Cet attribut n'a d'effet que lors de l'analyse d'un flot de caractères.
ReadMore
Sub : la valeur associée doit être une fonction anonyme à exécuter à l'issue de la reconnaissance du token. Cette fonction n'est utilisée qu'avec les analyseurs de la classe Parse::Lex ou Parse::CLex.
Sub
Parse::CLex
Exemple. new Parse::Token::Simple(Name => 'remainder', Regex => '[^/\'\"]+', ReadMore => 1);
La définition de ces tokens comporte trois expressions régulières. Lors de l'analyse d'un flot de données, de nouvelles données sont lues tant que la fin du token n'est pas atteinte.
Regex : La valeur associée doit être une référence à un tableau qui contient trois expressions régulières.
Sub : la valeur associée doit être une fonction anonyme à exécuter à l'issue de la reconnaissance du token. Cette fonction n'est utilisée avec les analyseurs de la classe Parse::Lex ou Parse::CLex.
Parse::Token::Quoted est une sous-classe de Parse::Token::Segmented. Elle permet de reconnaître des chaînes de caractères entre guillemets ou apostrophes.
Exemples.
--------------------------------------------------------- Début Fin Littéralisation --------------------------------------------------------- ' ' '' " " "" " " \ ---------------------------------------------------------
End : La valeur associée est une expression régulière permettant de reconnaître la fin du token.
End
Escape : La valeur associée indique le caractère utilisé pour littéralisater le délimiteur. Par défaut on considère qu'un doublement du caractère de fin littéralise ce caractère.
Escape
Start : La valeur associée est une expression régulière permettant de reconnaître le début du token.
Start
Exemple. new Parse::Token::Quoted(Name => 'squotes', Handler => 'string', Escape => '\\', Quote => qq!\'!, );
Parse::Token::Delimited est une sous-classe de Parse::Token::Segmented. Elle permet, par exemple, de reconnaître des commentaires C.
--------------------------------------------------------- Début Fin Contrainte Sur le contenu --------------------------------------------------------- /* */ Commentaire C <!-- --> Pas de '--' Commentaire XML <!-- --> Commentaire SGML <? ?> Processing instruction en SGML/XML ---------------------------------------------------------
Exemple. new Parse::Token::Delimited(Name => 'comment', Start => '/[*]', End => '[*]/' );
---------------------------------------------------------- Début Fin Contrainte Sur le contenu ---------------------------------------------------------- ( ) Symbolic Expressions { } Rich Text Format Groups ----------------------------------------------------------
L'implémentation des sous-classes de tokens n'est pas complète pour les analyseurs de la classe Parse::CLex. Je n'ai d'ailleurs pas trop envi de le faire, sachant qu'une implémentation pour les classes Parse::Lex et Parse::LexEvent ne paraît tout à fait suffisante.
Philippe Verdret
La version 2.0 doit beaucoup aux suggestions de Vladimir Alexiev. Ocrat a largement contribué à l'amélioration de cette documentation. Merci également aux nombreuses personnes qui m'ont fait des remarques et parfois envoyés des corrections de bugs.
Friedl, J.E.F. Mastering Regular Expressions. O'Reilly & Associates 1996.
Mason, T. & Brown, D. - Lex & Yacc. O'Reilly & Associates, Inc. 1990.
Copyright (c) 1995-1999 Philippe Verdret. All rights reserved. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
1 POD Error
The following errors were encountered while parsing the POD:
Non-ASCII character seen before =encoding in 'Définition'. Assuming CP1252
To install Parse::Lex, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Parse::Lex
CPAN shell
perl -MCPAN -e shell install Parse::Lex
For more information on module installation, please visit the detailed CPAN module installation guide.