Bonjour,

J'essaie de lire un fichier .org avec une grammaire.
Je suis parvenu à lire des fichiers en liste et/ou en récursif, mais quand le fichier contient une nouvelle tâche avec une indentation en moins, je coince.
Le code ci-dessous match chaque fichier (simulé dans $file), mais , dernier exemple, place en niveau 2 une tâche qui devrait être en niveau 1. Ce qui me paraît normal vu le code. J'ai essayé la ligne 12, mais ça ne match pas.

Une idée ?

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
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/usr/bin/env perl6
 
use v6;
use Data::Dump;
use Grammar::Tracer;
 
my $level;
grammar OrgMode {
    rule  TOP       { ^ <tasks> $ }
    rule  tasks     {  \n?<task>+ %% \n}
    token task      { <content> <tasks>? {$level=""}}
#    token task      { <content> <tasks>? {$level=$level.substr(0, *-1)}}
    token content   { ^^ ($level "*"+)" " .+? $$ {$level=$0.Str}}
}
 
class OM-actions {
    method TOP($/) {
        make $<tasks>.made;
    }
    method tasks($/) {
        make $<task>».made ;
    }
    method task($/) {
        my %task;
        %task{"task"}=$<content>.made;
        %task{"sub-task"}=$<tasks>.made if $<tasks>.made;
        make  %task;
    }
    method content($/) {
        make $/.Str ;
    }
}
 
my $file =
"* juste un header 1
 
* juste deux header 1
* header 2
 
* juste 3 header 1
* header 2
* header 3
 
* juste un header 1 et un sub
** sub-header 1
 
* juste un header 1 et deux sub *
** sub-header 1
** sub-header 2
 
* juste un header 1 et un sub et un sub-sub
** sub-header 1
*** sub-sub-header 1
 
* 2 header 1 et un sub au milieu
** sub-header 1
* header 2"
;
 
say "\n" x 10;
sub parse_file($file) {
    say $file;
    say "";
    $level="";
#    say OrgMode.parse($file);
    say Dump OrgMode.parse($file,:actions(OM-actions)).made;
    say "---------------------------------------------------------------------------------------";
}
 
parse_file($_) for split("\n\n",$file);