Bonjour,

Je continue à explorer les possibilités de l'analyse syntaxique en Perl6 et voici la question que, malheureusement, je n'arrive pas à résoudre seul.
J'aimerai pouvoir analyser un chemin d'accès (unix) à un fichier. Ce chemin peut être composé de variables d'environnements ou pas. S'il y a des variables d'environnements, elles doivent être remplacées par leurs valeurs.
exemple :
(avec export $toto = totoenv)
la chaine titi/$toto/tata/fichier doit devenir titi/totoenv/tata/fichier.

Le code suivant trouve bien l'arbre syntaxique adéquat:

################
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/opt/rakudo-star-2016.10/bin/perl6
use v6;
 
grammar TEST {
 
rule  TOP     { :i \s*  [<chemin>]<file> }
 
    rule chemin { :i \s* [<slash>] *[<dir><slash>] *}
    rule dir     {  <varenv> | <mot> }
    token varenv {'$'<mot> }
    token file     { .* }
    token mot     { <[a..z A..Z 0..9 =\-_!~'():@&+$,\']>+ }
    token slash     { '/' }
}
 
my $script = "titi/\$toto/tata/file" ;
my $scr = TEST.parse($script);
say $scr;
####################
===>
「titi/$toto/tata/file」
chemin => 「titi/$toto/tata/」
dir => 「titi」
mot => 「titi」
slash => 「/」
dir => 「$toto」
varenv => 「$toto」
mot => 「toto」
slash => 「/」
dir => 「tata」
mot => 「tata」
slash => 「/」
file => 「file」
Par contre, je n'arrive pas à obtenir un arbre syntaxique modifié conformément à mes besoins :
J'ai essayé plusieurs solutions mais sans succès. Par exemple :
##########################
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/opt/rakudo-star-2016.10/bin/perl6
use v6;
 
grammar TEST {
 
rule  TOP     { :i \s*  [<chemin>]<file> }
 
    rule chemin { :i \s* [<slash>] *[<dir><slash>] *}
    rule dir     {  <varenv> | <mot> }
    token varenv {'$'<mot> }
    token file     { .* }
    token mot     { <[a..z A..Z 0..9 =\-_!~'():@&+$,\']>+ }
    token slash     { '/' }
}
 
class ActionsTest {
    method chemin ($/) { $/.make( ~$/); }
    method dir ($/) { $/.make( ~$/); }
    method varenv ($/) { $/.make( %*ENV{$<chemin><dir><varenv><mot>}); }
    method mot ($/) { $/.make( ~$/); }
    method file($/) { $/.make( ~$/); }
    method TOP($/) { $/.make( ~$/); }
 
}
 
 
my $actions = ActionsTest.new;
my $script = "titi/\$toto/tata/file" ;
my $scr = TEST.parse($script,:$actions);
say $scr;
say $scr.made;
###########################
===>
Use of Nil in string context
in method varenv at ./test07.pl6 line 20
「titi/$toto/tata/file」
chemin => 「titi/$toto/tata/」
dir => 「titi」
mot => 「titi」
slash => 「/」
dir => 「$toto」
varenv => 「$toto」
mot => 「toto」
slash => 「/」
dir => 「tata」
mot => 「tata」
slash => 「/」
file => 「file」
titi/$toto/tata/file
------
(Bien sur, la ligne 20 correspond à :
method varenv ($/) { $/.make( %*ENV{$<chemin><dir><varenv><mot>}); } )
Je ne comprend pas bien pourquoi j'ai ce message de "Use of Nil".
D'autant plus que j'ai également ce message même lorsque je simplifie le chemin à $toto/file :
===>
Use of Nil in string context
in method varenv at ./test08.pl6 line 20
「$toto/file」
chemin => 「$toto/」
dir => 「$toto」
varenv => 「$toto」
mot => 「toto」
slash => 「/」
file => 「file」
$toto/file
---------------------

Enfin, dernier point, en simplifiant à l'extrême, j'ai trouvé un moyen d'évaluer une variable d'environnement unix en perl :
###########################
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/opt/rakudo-star-2016.10/bin/perl6
use v6;
 
grammar TEST {
 
rule  TOP     { :i \s*  <varenv>  }
 
    token varenv {'$'<mot> }
    token mot     { <[a..z A..Z 0..9 =\-_!~'():@&+$,\']>+ }
}
 
class ActionsTest {
    method TOP ($/) { $/.make( ~%*ENV{$<varenv><mot>}); }
}
 
my $actions = ActionsTest.new;
my $script = "\$toto" ;
my $scr = TEST.parse($script,:$actions);
 
say $scr;
say $scr.made;
###########################
===>
「$toto」
varenv => 「$toto」
mot => 「toto」
totoenv
----------------------------------

Mais dés que j'essaie de mettre %*ENV dans une autre méthode que la méthode TOP, je reviens à l'erreur "Use of Nil ..." et la variable d'environnement n'est pas évalué
######################
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/opt/rakudo-star-2016.10/bin/perl6
use v6;
grammar TEST {
 
rule  TOP     { :i \s*  <varenv>  }
 
    token varenv {'$'<mot> }
    token mot     { <[a..z A..Z 0..9 =\-_!~'():@&+$,\']>+ }
}
 
class ActionsTest {
    method varenv ($/) { $/.make( %*ENV{$<varenv><mot>}); }
    method TOP ($/) { $/.make( ~$/); }
}
 
 
my $actions = ActionsTest.new;
my $script = "\$toto" ;
my $scr = TEST.parse($script,:$actions);
 
say $scr;
say $scr.made;
######################
===>
Use of Nil in string context
in method varenv at ./test052.pl6 line 14
「$toto」
varenv => 「$toto」
mot => 「toto」
$toto

Voilà où je bloque, si vous avez une solution, je suis preneur...

Merci beaucoup pour votre aide.
Bien cordialement,