Bonne année 2017 avec plein de joli code sans bug ...
La mauvaise nouvelle de ce début d'année ,c'est que je continue mes tests sur Perl6 et ses possibilités d'analyse lexicale/syntaxique.
Et que comme d'habitude, j'ai des questions ...
L'exercice du jour consiste à essayer de transformer dans un ordre sql " select dummy, sequencetoto.nextval from dual " (syntaxe Oracle) en " select dummy, nextval('sequencetoto') from dual " (syntaxe PostgreSQL)
ce que le code suivant réalise plûtot bien :
( même si un caractère blanc disparait entre le dummy et nextval ... )
ce qui donne
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 cat ./nextval04.pl6 #!/opt/rakudo-star-2016.10/bin/perl6 use v6; use Grammar::Tracer; #use Grammar::Debugger; grammar Test { rule TOP { [<text> <nextvaltop> ] <textfin> } token nextvaltop { <sequence> '.'<nextval> } token sequence { \w+ } token nextval { :i 'nextval' } regex text { .+? } regex textfin { .+ } } class TestCompute { method TOP ($/) { make $<text> ~ $<nextvaltop>.made ~ $<textfin>; } method nextvaltop ($/) { make $<nextval> ~ "('" ~ $<sequence> ~ "')" ; } } say Test.parse('select dummy, totoseq.nextval from dual', actions => TestCompute).made;
La où je n'y arrive plus, c'est si je veux transformer plusieurs sequences dans le même ordre, par exemple : " select dummy, sequencetoto.nextval, sequencetiti.nextval from dual " (syntaxe Oracle) en " select dummy, nextval('sequencetoto'),nextval('sequencetiti') from dual "
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 ./nextval04.pl6 TOP | text | * MATCH "s" | nextvaltop | | sequence | | * MATCH "dummy" | * FAIL | nextvaltop | | sequence | | * MATCH "dummy" | * FAIL | nextvaltop | | sequence | | * FAIL | * FAIL | nextvaltop | | sequence | | * MATCH "totoseq" | | nextval | | * MATCH "nextval" | * MATCH "totoseq.nextval" | textfin | * MATCH "from dual" * MATCH "select dummy, totoseq.nextval from dual" select dummy,nextval('totoseq')from dual
J'arrive bien à faire obtenir l'AST correspond en modifiant ma grammaire comme suit :
ce qui donne :
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 cat ./nextval03.pl6 #!/opt/rakudo-star-2016.10/bin/perl6 use v6; use Grammar::Tracer; #use Grammar::Debugger; grammar Test { rule TOP { [<text> <nextvaltop> ]* <textfin> } token nextvaltop { <sequence> '.'<nextval> } token sequence { \w+ } rule nextval { :i 'nextval' } regex text { .+? } regex textfin { .+ } } class TestCompute { method TOP ($/) { make $<text> ~ $<nextvaltop>.made ~ $<textfin>; } method nextvaltop ($/) { make $<nextval> ~ "('" ~ $<sequence> ~ "')" ; } } say Test.parse('select totoseq.nextval, dummy, titiseq.NEXTVAL from dual');
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 ./nextval03.pl6 TOP | text | * MATCH "s" | nextvaltop | | sequence | | * MATCH "totoseq" | | nextval | | * MATCH "nextval" | * MATCH "totoseq.nextval" | text | * MATCH "," | nextvaltop | | sequence | | * MATCH "dummy" | * FAIL | nextvaltop | | sequence | | * MATCH "dummy" | * FAIL | nextvaltop | | sequence | | * FAIL | * FAIL | nextvaltop | | sequence | | * MATCH "titiseq" | | nextval | | * MATCH "NEXTVAL " | * MATCH "titiseq.NEXTVAL " | text | * MATCH "f" | nextvaltop | | sequence | | * MATCH "dual" | * FAIL | nextvaltop | | sequence | | * MATCH "dual" | * FAIL | nextvaltop | | sequence | | * FAIL | * FAIL | textfin | * MATCH "from dual" * MATCH "select totoseq.nextval, dummy, titiseq.NEXTVAL from dual" 「select totoseq.nextval, dummy, titiseq.NEXTVAL from dual」 text => 「select」 nextvaltop => 「totoseq.nextval」 sequence => 「totoseq」 nextval => 「nextval」 text => 「, dummy,」 nextvaltop => 「titiseq.NEXTVAL 」 sequence => 「titiseq」 nextval => 「NEXTVAL 」 textfin => 「from dual」
mais si j'essaie de modifier l'AST :
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 #!/opt/rakudo-star-2016.10/bin/perl6 use v6; use Grammar::Tracer; #use Grammar::Debugger; grammar Test { rule TOP { [<text> <nextvaltop> ]* <textfin> } token nextvaltop { <sequence> '.'<nextval> } token sequence { \w+ } rule nextval { :i 'nextval' } regex text { .+? } regex textfin { .+ } } class TestCompute { method TOP ($/) { make $<text> ~ $<nextvaltop>.made ~ $<textfin>; } method nextvaltop ($/) { make $<nextval> ~ "('" ~ $<sequence> ~ "')" ; } } say Test.parse('select dummy,totoseq.nextval, titiseq.nextval from dual', actions => TestCompute).made;
j'obtiens :
snif ...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 No such method 'made' for invocant of type 'Array' in method TOP at ./nextval03.pl6 line 16 in regex TOP at ./nextval03.pl6 line 7 in block at /opt/rakudo-star-2016.10/share/perl6/site/sources/88A197C57F6C4623C1071F68DFC42E86CA5F4B4D (Grammar::Tracer) line 21 in block <unit> at ./nextval03.pl6 line 21
Du coup je me demande si ce que je veux faire est bien possible ...
Voilà,
Merci pour votre aide.
Bien cordialement,
Partager