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;
===>
Par contre, je n'arrive pas à obtenir un arbre syntaxique modifié conformément à mes besoins :「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」
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,
Partager