=head1 NAME C - Définition des tokens utilisés par C =head1 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 =head1 DESCRIPTION La classe C et ses dérivées permettent de définir les tokens utilisés par C ou C. La création des tokens peut se faire au moyen des méthodes C ou C. La méthode C du package C crée indirectement des instances des tokens à reconnaître. Les méthodes C ou C du package C permettent d'interfacer l'analyseur lexical avec un analyseur syntaxique de type récursif descendant. Pour un interfaçage avec C voir le package C. L'inclusion de C se fait indirectement par un C ou C. =head1 Méthodes =over 4 =item action Retourne la fonction anonyme définie dans l'objet C. =item factory LIST =item factory ARRAY_REF La méthode C 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 C ou d'une classe qui en dérive. C permet de créer des tokens à partir de spécifications de type attribut-valeur : Parse::Token->factory([Type => 'Simple', Name => 'EXAMPLE', Regex => '.+']); C indique le type de chaque token à créer (le préfixe de package n'est pas indiqué). C 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}, '']; } C<${$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é C<$_[1]> qui correspond au texte reconnu par l'expression régulière. Ce texte associé au token doit être retourné par la fonction anonyme. =item 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. =item getText Retourne la chaîne de caractères reconnue au moyen de l'objet C. Synonyme de la méthode C. =item isnext EXPR =item 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. =item name Retourne le nom du token. =item 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 C retourne la chaîne trouvée et met le statut de l'objet à vrai. =item new SYMBOL_NAME, REGEXP, SUB =item new SYMBOL_NAME, REGEXP Crée un objet de type C ou C. Les arguments de la méthode C sont dans l'ordre : un nom symbolique, une expression régulière et éventuellement une fonction anonyme. Les sous-classes de C 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 C Dans le second cas l'instance appartient à la classe C. 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 C utilise C<(?:.*?)>, 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 C pour inclure la nouvelle-ligne dans les caractères reconnus par "C<.>" : 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 I.) La fonction anonyme est exécutée au moment ou le token est reconnu par l'analyseur lexical. Cette fonction possède deux arguments : C<$_[0]> contient l'instance de token, C<$_[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 C<$1>, C<$2>, ... qui correspondent aux parenthèses placées dans l'expression régulière. =item regexp Retourne l'expression régulière définie dans l'objet C. =item 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. =item setText EXPR La valeur de EXPR définit la chaîne de caractères associée au token. Synonyme de la méthode C. =item status EXPR =item status Indique si la dernière recherche du token a réussie ou échouée. C permet de forcer le statut à la valeur dénotée par EXPR. =item text EXPR =item text C 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. =item trace OUTPUT =item trace Méthode de classe qui active/désactive une trace de l'analyse lexicale. C peut être un nom de fichier ou une référence à un filehandle vers laquelle la trace va être dirigée. =back =head1 Sous-classes de Parse::Token Des sous-classes de la classe C 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 : C : permet d'insérer des expressions Perl entre deux tokens de l'analyseur lexical. C : les tokens de cette classe sont définis au moyen d'une seule expression régulière. C : les tokens de cette classe sont définis au moyen de trois expressions régulières. La lecture de nouvelles données est automatique. C : permet de reconnaître, par exemple, des commentaires C. C : permet de reconnaître, par exemple, des chaînes de caractères entre guillemets. C : 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. =head2 Parse::Token::Action Les tokens de la classe C 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 : =over =item * C<$LEX_BUFFER> : contenu du buffer à analyser =item * C<$LEX_LENGTH> : longueur de la chaîne de caractères en cours d'analyse =item * C<$LEX_RECORD> : numéro de l'enregistrement en cours d'analyse =item * C<$LEX_OFFSET> : nombre de caractère déjà consommés depuis le début de l'analyse =item * C<$LEX_POS> : position atteinte par l'analyse en nombre de caractères depuis le début du buffer. =back Le constructeur de la classe accepte les attributs suivants : =over =item * C : le nom du token =item * C : une expression Perl =back 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" ;!, ); =head2 Parse::Token::Simple Le constructeur de la classe accepte les attributs suivants : =over =item * C : la valeur indique un nom fonction à appeler lors d'une analyse conduite par un analyseur de la classe C. =item * C : la valeur associée est le nom du token. =item * C : La valeur associée est une expression régulière correspondant au motif à reconnaître. =item * C : 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. =item * C : 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 C ou C. =back Exemple. new Parse::Token::Simple(Name => 'remainder', Regex => '[^/\'\"]+', ReadMore => 1); =head2 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 : =over =item * C : la valeur indique un nom fonction à appeler lors d'une analyse conduite par un analyseur de la classe C. =item * C : la valeur associée est le nom du token. =item * C : La valeur associée doit être une référence à un tableau qui contient trois expressions régulières. =item * C : 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 C ou C. =back =head2 Parse::Token::Quoted C est une sous-classe de C. 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 : =over =item * C : La valeur associée est une expression régulière permettant de reconnaître la fin du token. =item * C : 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. =item * C : la valeur indique un nom fonction à appeler lors d'une analyse conduite par un analyseur de la classe C. =item * C : la valeur associée est le nom du token. =item * C : La valeur associée est une expression régulière permettant de reconnaître le début du token. =item * C : 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 C ou C. =back Exemple. new Parse::Token::Quoted(Name => 'squotes', Handler => 'string', Escape => '\\', Quote => qq!\'!, ); =head2 Parse::Token::Delimited C est une sous-classe de C. 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 : =over 4 =item * C : La valeur associée est une expression régulière permettant de reconnaître la fin du token. =item * C : la valeur indique un nom fonction à appeler lors d'une analyse conduite par un analyseur de la classe C. =item * C : la valeur associée est le nom du token. =item * C : La valeur associée est une expression régulière permettant de reconnaître le début du token. =item * C : 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 C ou C. =back Exemple. new Parse::Token::Delimited(Name => 'comment', Start => '/[*]', End => '[*]/' ); =head2 Parse::Token::Nested - Non définie Exemples. ---------------------------------------------------------- Début Fin Contrainte Sur le contenu ---------------------------------------------------------- ( ) Symbolic Expressions { } Rich Text Format Groups ---------------------------------------------------------- =head1 BUGS L'implémentation des sous-classes de tokens n'est pas complète pour les analyseurs de la classe C. Je n'ai d'ailleurs pas trop envi de le faire, sachant qu'une implémentation pour les classes C et C ne paraît tout à fait suffisante. =head1 AUTEUR Philippe Verdret =head1 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. =head1 REFERENCES Friedl, J.E.F. Mastering Regular Expressions. O'Reilly & Associates 1996. Mason, T. & Brown, D. - Lex & Yacc. O'Reilly & Associates, Inc. 1990. =head1 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. =cut