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


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;
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
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
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 "

J'arrive bien à faire obtenir l'AST correspond en modifiant ma grammaire comme suit :

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');
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
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 :

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

Du coup je me demande si ce que je veux faire est bien possible ...

Voilà,

Merci pour votre aide.
Bien cordialement,