NAME

Parse::Lex - Générateur d'analyseurs lexicaux (Alpha 1.18).

SYNOPSIS

	require 5.004;

	use Parse::Lex;
	@token = (
	  qw(
	     ADDOP    [-+]
	     LEFTP    [\(]
	     RIGHTP   [\)]
	     INTEGER  [1-9][0-9]*
	     NEWLINE  \n
	     
	    ),
	  qw(STRING),   [qw(" (?:[^"]+|"")* ")],
	  qw(ERROR  .*), sub {
	    die qq!can\'t analyze: "$_[1]"!;
	  }
	 );

	Parse::Lex->trace;  # Class method
	$lexer = Parse::Lex->new(@token);
	$lexer->from(\*DATA);
	print "Tokenization of DATA:\n";

	TOKEN:while (1) {
	  $token = $lexer->next;
	  if (not $lexer->eoi) {
	    print "Line $.\t";
	    print "Type: ", $token->name, "\t";
	    print "Content:->", $token->getstring, "<-\n";
	  } else {
	    last TOKEN;
	  }
	}

	__END__
	1+2-5
        "This is a multiline
        string with an embedded "" in it"
        this is an invalid string with a "" in it"

DESCRIPTION

La classe Parse::Lex permet de créer des analyseurs lexicaux. Un analyseur lexical est spécifié au moyen d'un liste de lexèmes (token) passée en argument à la méthode new de la classe Parse::Lex.

Parse::Lex ne fonctionne qu'avec perl 5.004. Si votre version est antérieure, utilisez la sous-classe Parse::CLex.

Les analyseurs générés par ces deux classes exploitent des stratégies d'analyse différentes :

1. Parse::Lex utilise pos(), associé à "\G" pour effectuer l'analyse,

2. Parse::CLex effectue une analyse avec consommation des tokens reconnus.

Attention ! Les analyseurs de la classe Parse::CLex ne permettent pas d'utiliser des expressions régulières avec ancrage.

Les lexèmes sont des objets de la classe Parse::Token, livré avec Parse::Lex. La définition d'un lexème comporte ordinairement deux arguments : un non symbolique (comme INTEGER), suivi d'une expression régulière. Si une fonction anonyme est donnée en troisième argument, elle est exécutée lorsque le lexème est reconnu. Le retour de cette fonction sera le contenu du token.

L'ordre dans lequel l'analyseur lexical examine les expressions régulières est déterminé par l'ordre dans lequel ces expressions sont passées en argument à la méthode new. Le lexème retourné par l'analyseur lexical correspond à la première expression qui s'apparie avec le début du flot de caractères à analyser (la stratégie est différence de celle adoptée par l'analyseur lexical "lex" qui retourne la plus longue chaîne de toutes celles qu'il est possible de reconnaître). Le lexème est un objet de la classe Parse::Token.

L'analyseur peut être utilisé pour analyser une chaîne de caractères isolée ou un flot de données provenant d'une entrée quelconque. En fin de flot l'analyseur retourne un objet Token dont le nom est EOI (End Of Input).

Méthodes

buffer EXPR
buffer

Retourne le contenu du buffer interne à l'analyseur lexical. Avec une expression en argument, place le résultat de l'expression dans le buffer.

eoi

Retourne vrai lorsqu'il n'y a plus de données à analyser.

every ANON

Évite de devoir écrire une boucle de lecture pour analyser un flot de données. ANON est une fonction anonyme executée après la reconnaissance de chaque lexème.

Pour segmenter la chaîne "1+2" on peut par exemple écrire :

use Parse::Lex;

$lexer = Parse::Lex->new(
  qw(
     ADDOP [-+]
     INTEGER \d+
    ));

$lexer->from("1+2");
$lexer->every (sub { 
  print $_[0]->name, "\t";
  print $_[0]->getstring, "\n"; 
});

Le premier argument de la fonction anonyme est l'objet Token reconnu.

from EXPR

from permet d'indiquer la source des données à analyser. L'argument de cette méthode peut être une référence à un filehandle ou une liste de chaînes de caractères.

Exemple.

$lexer->from(\*DATA);
$lexer->from('les données à analyser');
flush

Si la conservation des chaînes consommées est activée, flush retourne et vide le buffer contenant les chaînes de caractères reconnues jusqu'ici.

getsub

getsub retourne la fonction anonyme réalisant l'analyse lexicale.

Exemple.

	my $token = '';
	my $sub = $lexer->getsub;
	while (($token = &$sub()) ne $Token::EOI) {
	  print $token->name, "\t";
	  print $token->getstring, "\n";
	}
    
   # or 
	
	my $token = '';
	local *tokenizer = $lexer->getsub;
	while (($token = tokenizer()) ne $Token::EOI) {
	  print $token->name, "\t";
	  print $token->getstring, "\n";
	}
hold EXPR
hold

Active/desactive la conservation des chaînes consommées. Retourne la valeur courante. Peut être utilisée comme méthode de classe.

On peut obtenir le contenu du buffer au moyen de la méthode flush qui a également pour effet de vider le buffer.

less EXPR

La valeur de EXPR est placée au début du flot de données.

next

Provoque la recherche du prochain lexème. Retourne l'objet Token reconnu. Retourne l'objet Token::EOI en fin de données.

Exemples.

$lexer = Parse::Lex->new(@token);
print $lexer->next->name;   # print the token type
print $lexer->next->text;   # print the token content
new

Crée et retourne un nouvel analyseur lexical. L'argument de la méthode est une liste de triplets comportant : le nom symbolique du lexème, l'expression régulière nécessaire à sa reconnaissance et éventuellement une fonction anonyme exécutée lors de la reconnaissance du lexème. Pour chaque triplet, un objet de type Parse::Token est créé.

L'analyseur lexical construit par new cherche tour à tour à apparier chaque expression régulière avec le début du flot de données à analyser. L'ordre examen des expressions régulières est donné par l'ordre dans lequel elles sont passées en argument à la méthode new.

Parse::Lex peut reconnaître des lexèmes disposés sur plusieurs enregistrements. Si la définition du token comporte plusieurs expressions régulières (et est placée dans un tableau anonyme) Parse::Lex lira autant d'enregistrement que nécessaire pour reconnaître le token (voir la documentation de la classe Parse::Token). Lorsque que le motif du début est trouvé, l'analyseur en cherche la fin, et si besoin est, lit de nouveaux enregistrements. Attention, il n'y a pas de rebroussement en cas d'échec.

newset

Peut être utilisé pour créer un ensemble de lexèmes qui ne sont pas dans l'automate d'analyse. On pourra pas exemple écrire :

%keywords = 
  qw (
      PROC  undef
      FUNC  undef
      RETURN undef
      IF    undef
      ELSE  undef
      WHILE undef
      PRINT undef
      READ  undef
     );
$lexer->newset(%keywords);

et installer ces tokens dans une table des symboles de la manière suivante :

foreach $name (keys %keywords) {
  $symbol{"\L$name"} = [${$name}, ''];
}

${$name} est l'objet 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 CONTENT
 }

Ce qui permet d'indiquer que tout symbole dont le type est inconnu est une variable.

Remarque. La fonction anonyme associée au token reçoit en argument l'objet token. Le contenu du token est le retour de la fonction anonyme.

offset

Retourne le nombre de caractères déjà consommé depuis le début du flot de données analysé.

pos EXPR
pos

pos EXPR fixe la position de début du prochain token à reconnaître dans l'enregistrement courant. pos retourne le nombre de caractères déjà consommé dans l'enregistrement courant.

readline

Effectue la lecture des données sur l'entrée spécifiée par la méthode from. Retourne le résultat de la lecture.

recordno

Retourne le numéro de l'enregistrement courant. Retourne toujours 1 si on analyse une chaîne de caractères. La méthode readline incrémente ce numéro.

reset

Vide le buffer interne à l'analyseur lexical et efface tout token déjà reconnu.

skip EXPR
skip

EXPR est une expression régulière définissant le séparateur de lexème (par défaut [ \t]+). Retourne ce séparateur si EXPR est omis. Peut être utilisée comme méthode de classe.

Attention ! Le changement du motif à "sauter" provoque une recompilation de l'analyseur lexical.

token

Retourne l'objet correspondant au dernier lexème reconnu. En l'absence de token lu, retourne un token spécial dont le nom est default token.

settoken TOKEN

Force le lexème à TOKEN. Utile pour requalifier un lexème à l'intérieur de la fonction anonyme associée à ce lexème.

A terme annule et remplace la méthode tokenis(TOKEN).

trace OUTPUT
trace

Méthode de classe qui active le mode trace. L'activation du mode trace doit avoir lieu avant la création de l'analyseur lexical. Le mode peut être ensuite désactivé par un nouvel appel de la méthode.

OUTPUT peut être un nom de fichier ou une référence à un filehandle vers laquelle la trace va être dirigée.

EXEMPLES

ctokenizer.pl - Segmentation d'un flot de données au moyen de la classe Parse::CLex.

tokenizer.pl - Segmentation d'un flot de données au moyen de la classe Parse::Lex.

every.pl - Utilisation de la méthode every.

BUGS

Parse::Lex ne fonctionne qu'avec perl 5.004. Si votre version de Perl est antérieure, utilisez la classe Parse::CLex.

Les analyseurs de la classe Parse::CLex ne permettent pas d'utiliser des expressions régulières avec ancrage.

AUTEUR

Philippe Verdret

AVERTISSEMENT

Je considère que la présente version des classes Token.pm/Lex.pm est expérimentale. Ces classes peuvent évoluer de façon notable, en particulier en fonction des remarques et des suggestions que vous voudrez bien m'envoyer.

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-1997 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.

4 POD Errors

The following errors were encountered while parsing the POD:

Around line 3:

Non-ASCII character seen before =encoding in 'Générateur'. Assuming CP1252

Around line 91:

'=item' outside of any '=over'

Around line 302:

Unterminated C<...> sequence

Around line 324:

You forgot a '=back' before '=head1'