NAME
Parse::Token
- Définition des tokens utilisés par Parse::Lex
SYNOPSIS
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
DESCRIPTION
La classe Parse::Token
et ses dérivées permettent de définir les tokens utilisés par Parse::Lex
ou 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.
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
.
L'inclusion de Parse::Token
se fait indirectement par un use Parse::Lex
ou use Parse::LexEvent
.
Méthodes
- action
-
Retourne la fonction anonyme définie dans l'objet
Parse::Token
. - factory LIST
- factory ARRAY_REF
-
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 classeParse::Token
ou d'une classe qui en dérive.factory(ARRAY_REF)
permet de créer des tokens à partir de spécifications de type attribut-valeur :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é).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.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. - get EXPR
-
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.
- getText
-
Retourne la chaîne de caractères reconnue au moyen de l'objet
Parse::Token
.Synonyme de la méthode
text()
. - isnext EXPR
- isnext
-
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.
- name
-
Retourne le nom du token.
- next
-
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. - new SYMBOL_NAME, REGEXP, SUB
- new SYMBOL_NAME, REGEXP
-
Crée un objet de type
Parse::Token::Simple
ouParse::Token::Segmented
. Les arguments de la méthodenew()
sont dans l'ordre : un nom symbolique, une expression régulière et éventuellement une fonction anonyme. Les sous-classes deParse::Token
permettent une spécification des tokens au moyen d'une liste d'attribut-valeurs.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 classeParse::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 ".
" :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.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. - regexp
-
Retourne l'expression régulière définie dans l'objet
Parse::Token
. - set LISTE
-
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.
- setText EXPR
-
La valeur de EXPR définit la chaîne de caractères associée au token.
Synonyme de la méthode
text(EXPR)
. - status EXPR
- status
-
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. - text EXPR
- text
-
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. - trace OUTPUT
- trace
-
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.
Sous-classes de Parse::Token
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::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::Quoted
: permet de reconnaître, par exemple, des chaînes de caractères entre guillemets.
Parse::Token::Nested
: permet de reconnaître des structures imbriquées, telles que les expressions parenthésées. NON DéFINIE.
La création de ces classes est récente et comporte sans aucun doute des bugs.
Parse::Token::Action
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_LENGTH
: longueur de la chaîne de caractères en cours d'analyse$LEX_RECORD
: numéro de l'enregistrement en cours d'analyse$LEX_OFFSET
: nombre de caractère déjà consommés depuis le début de l'analyse$LEX_POS
: position atteinte par l'analyse en nombre de caractères depuis le début du buffer.
Le constructeur de la classe accepte les attributs suivants :
Name
: le nom du tokenExpr
: une expression Perl
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"
;!,
);
Parse::Token::Simple
Le constructeur de la classe accepte les attributs suivants :
Handler
: la valeur indique un nom fonction à appeler lors d'une analyse conduite par un analyseur de la classeParse::LexEvent
.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.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.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 classeParse::Lex
ouParse::CLex
.
Exemple. new Parse::Token::Simple(Name => 'remainder', Regex => '[^/\'\"]+', ReadMore => 1);
Parse::Token::Segmented
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.
Le constructeur de la classe accepte les attributs suivants :
Handler
: la valeur indique un nom fonction à appeler lors d'une analyse conduite par un analyseur de la classeParse::LexEvent
.Name
: la valeur associée est le nom du token.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 classeParse::Lex
ouParse::CLex
.
Parse::Token::Quoted
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
---------------------------------------------------------
' ' ''
" " ""
" " \
---------------------------------------------------------
Le constructeur de la classe accepte les attributs suivants :
End
: La valeur associée est une expression régulière permettant de reconnaître la fin du token.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.Handler
: la valeur indique un nom fonction à appeler lors d'une analyse conduite par un analyseur de la classeParse::LexEvent
.Name
: la valeur associée est le nom du token.Start
: La valeur associée est une expression régulière permettant de reconnaître le début du token.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 classeParse::Lex
ouParse::CLex
.
Exemple. new Parse::Token::Quoted(Name => 'squotes', Handler => 'string', Escape => '\\', Quote => qq!\'!, );
Parse::Token::Delimited
Parse::Token::Delimited
est une sous-classe de Parse::Token::Segmented
. Elle permet, par exemple, de reconnaître des commentaires C.
Exemples.
---------------------------------------------------------
Début Fin Contrainte
Sur le contenu
---------------------------------------------------------
/* */ Commentaire C
<!-- --> Pas de '--' Commentaire XML
<!-- --> Commentaire SGML
<? ?> Processing instruction
en SGML/XML
---------------------------------------------------------
Le constructeur de la classe accepte les attributs suivants :
End
: La valeur associée est une expression régulière permettant de reconnaître la fin du token.Handler
: la valeur indique un nom fonction à appeler lors d'une analyse conduite par un analyseur de la classeParse::LexEvent
.Name
: la valeur associée est le nom du token.Start
: La valeur associée est une expression régulière permettant de reconnaître le début du token.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 classeParse::Lex
ouParse::CLex
.
Exemple. new Parse::Token::Delimited(Name => 'comment', Start => '/[*]', End => '[*]/' );
Parse::Token::Nested - Non définie
Exemples.
----------------------------------------------------------
Début Fin Contrainte
Sur le contenu
----------------------------------------------------------
( ) Symbolic Expressions
{ } Rich Text Format Groups
----------------------------------------------------------
BUGS
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.
AUTEUR
Philippe Verdret
REMERCIEMENTS
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.
REFERENCES
Friedl, J.E.F. Mastering Regular Expressions. O'Reilly & Associates 1996.
Mason, T. & Brown, D. - Lex & Yacc. O'Reilly & Associates, Inc. 1990.
COPYRIGHT
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:
- Around line 3:
Non-ASCII character seen before =encoding in 'Définition'. Assuming CP1252