]> lifelog.hopto.org Git - PerlCNF.git/commitdiff
Anechoic handling bettered, main CNF tag parsing routine revisited.
authorWill Budic <redacted>
Wed, 5 Feb 2025 22:49:04 +0000 (09:49 +1100)
committerWill Budic <redacted>
Wed, 5 Feb 2025 22:49:04 +0000 (09:49 +1100)
system/modules/CNFMeta.pm
system/modules/CNFParser.pm

index 16496b25b57168a9d63fd49d46b80e496035c532..532dfbe20f005435b2076547e01ddad90225ce8c 100644 (file)
@@ -13,7 +13,7 @@ use strict;
 use warnings; no warnings qw(experimental::signatures);
 
 ###
-# Returns the regular expresion for any of the meta constances.
+# Returns the regular expression for any of the meta constances.
 ##
 sub _meta {
     my $constance = shift;
@@ -27,6 +27,9 @@ sub _meta {
 ###
 # Priority order no. for instructions.
 use constant PRIORITY => qr/(\s*\_+PRIORITY\_(\d+)\_+\s*)/o;
+###
+# ANONYMOUS tag name assigned  where name is not given or tagged.
+use constant ANN => '__ANN__';
 
 ###
 # Globals, there is possible only four CNF data types.
@@ -40,7 +43,7 @@ my $cnt =0;  foreach(qw{BOOL INT NUMBER DATE TEXT}){$CNF_DATA_TYPES{$_}=++$cnt}
    $cnt =0; foreach(qw{IDX TABLE COLNAME})          {$REL_IDX{$_}=$cnt++};
 }
 ###
-# Global setting for SQL TEXT to CNF _TEXT_ specified data type range. Programatically changable.
+# Global setting for SQL TEXT to CNF _TEXT_ specified data type range. Programmatically changeable.
 our $SQL_CNF_VAR_LENGTH = 2024;
 
 sub import {
index af5bcd783be4a86104dbfcffd5fe0303c83f4328..60a5fdf412d650cbae24a4915de94b1a8deb30ee 100644 (file)
@@ -19,7 +19,7 @@ require CNFDateTime;
 ##no critic qw(Subroutines::RequireFinalReturn)
 ##no critic Perl::Critic::Policy::ControlStructures::ProhibitMutatingListFunctions
 
-use constant VERSION => '3.3.2';
+use constant VERSION => '3.3.3';
 use constant APP_STS => 'APP_SETTINGS';
 our @files;
 our %lists;
@@ -31,8 +31,10 @@ our $SQL;
 # Package fields are always global in perl!
 ###
 our %ANONS;
-#private -> Instance fields:
-                my $ANONS;
+###
+# Following is private -> Instance fields for package, every objects has its own not accessible from outside.
+###
+                my $anechoic; #<- Not setting here by purpose to package global. As anon sub here is ideally an method.
                 my @includes; my $CUR_SCRIPT;
                 my %instructs;
                 my $IS_IN_INCLUDE_MODE;
@@ -76,10 +78,16 @@ sub new { my ($class, $path, $attrs, $del_keys, $self) = @_;
         };
     }
     $CONSTREQ = $self->{CONSTANT_REQUIRED};
-    if (!$self->{ANONS_ARE_PUBLIC}){ #Not public, means are private to this object, that is, anons are not static.
-         $self->{ANONS_ARE_PUBLIC} = 0; #<- Caveat of Perl, if this is not set to zero, it can't be accessed legally in a protected hash.
-         $self->{__ANONS__} = {};
+
+    if ($self->{'ANONS_ARE_PUBLIC'}){
+        $anechoic = \%ANONS;
+    }else{
+        #Not public, means are private to this object, that is, anons are not static.        
+        $self->{ANONS_ARE_PUBLIC} = 0; #<- Caveat of Perl, if this is not set to zero, it can't be accessed legally in a protected hash.
+        $self->{__ANONS__} = {};
+        $anechoic = $self->{__ANONS__};
     }
+
     if(exists  $self->{'%LOG'}){
         if(ref($self->{'%LOG'}) ne 'HASH'){
             die '%LOG'. "passed attribute is not an hash reference."
@@ -160,21 +168,22 @@ sub _isTrue{
 }
 
 ###
-# Post parsing instructed special item objects. They have lower priority to Order of apperance and from CNFNodes.
+# Post parsing instructed special item objects. They have lower priority to Order of appearance and from CNFNodes.
 ##
 package InstructedDataItem {
 
     our %counters;
 
-    sub new { my ($class, $ele, $ins, $val) = @_;
-        my $priority = ($val =~ s/$meta_has_priority/""/sexi)?2:3; $val =~ s/$meta_priority/""/sexi;
+    sub new { my ($class, $ele, $ins, $val, $aid) = @_;
+        my $priority = ($val =~ s/$meta_has_priority/""/sexi)?2:3; 
+           $val =~ s/$meta_priority/""/sexi;
            $priority = $2 if $2;
         my $dataItemCounter;
         if(exists $counters{$ele}){
            $dataItemCounter = $counters{$ele};
         }else{
-            $dataItemCounter = {aid=>int(0)};
-            $counters{$ele} = $dataItemCounter;
+           $dataItemCounter = {aid=>int(0)};
+           $counters{$ele} = $dataItemCounter;
         }
         bless {
                 ele => $ele,
@@ -235,19 +244,22 @@ package PropertyValueStyle {
 # They can be; and are only dynamically set via the config instance directly.
 # That is, if it has the ANONS_ARE_PUBLIC property set, and by using the empty method of anon() with no arguments.
 # i.e. ${CNFParser->new()->anon()}{'MyDynamicAnon'} = 'something';
-# However a private config instance, will have its own anon's. And could be read only if it exist as a property, via this anon(NAME) method.
+# However a private config instance, will have its own anon's. And could be read only if it exist as an property, via this anon(NAME) method.
 # This hasn't been yet fully specified in the PerlCNF specs.
 # i.e. ${CNFParser->new({ANONS_ARE_PUBLIC=>0})->anon('MyDynamicAnon') # <-- Will not be available.
 ##
 sub anon {  my ($self, $n, $args)=@_;
-    my $anechoic = \%ANONS;
+
+    my $this_anechoic;
+
     if(ref($self) ne 'CNFParser'){
         $n = $self;
-    }elsif (not $self->{'ANONS_ARE_PUBLIC'}){
-        $anechoic = $self->{'__ANONS__'};
+        $this_anechoic = $anechoic #To what ever is globally set.
+    }else{
+        $this_anechoic = $self->{ANONS_ARE_PUBLIC} ? \%ANONS: $self->{__ANONS__};
     }
     if($n){
-        my $ret = %$anechoic{$n};
+        my $ret = %$this_anechoic {$n};
         return if !$ret;
         if($args){
             my $ref = ref($args);
@@ -255,7 +267,7 @@ sub anon {  my ($self, $n, $args)=@_;
                 my @arr = ($ret =~ m/(\$\$\$.+?\$\$\$)/gm);
                 foreach my $find(@arr) {# <- MACRO TAG translate. ->
                         my $s= $find; $s =~ s/^\$\$\$|\$\$\$$//g;#
-                        my $r = %$anechoic{$s};
+                        my $r = $this_anechoic -> {$s};
                         if(!$r && exists $self->{$s}){#fallback to maybe constant property has been seek'd?
                             $r = $self->{$s};
                         }
@@ -281,18 +293,19 @@ sub anon {  my ($self, $n, $args)=@_;
                     $cnt++;
                 }
             }else{
-                my $val =  %$anechoic{$args};
+                my $val =  $this_anechoic->{$args};
                 $ret =~ s/\$\$\$$args\$\$\$/$val/g;
                 warn "Scalar argument passed $args, did you mean array to pass? For property $n=$ret\n"
                                  unless $self and not $self->{ENABLE_WARNINGS}
             }
         }
         my $ref = ref($ret);
+        return $ret if $ref eq '';
         return $$ret if $ref eq "REF";
         return $ret->val() if $ref eq "CNFNode";
         return $ret;
     }
-    return $anechoic;
+    return $this_anechoic;
 }
 
 ###
@@ -432,7 +445,14 @@ sub template { my ($self, $property, %macros) = @_;
 
 #private to parser sub.
 sub doInstruction { my ($self,$e,$t,$v) = @_;
-    my $DO_ENABLED = $self->{'DO_ENABLED'};  my $priority = 0; my $isMetaConst;
+    my $DO_ENABLED = $self->{'DO_ENABLED'};  my $priority = 4; my $isMetaConst;
+    if(!$t && !$v && ref($e) eq 'InstructedDataItem'){
+       my   $itm = $e; 
+       $e = $itm->{ele} . $itm ->{aid};
+       $t = $itm->{ins};
+       $v = $itm->{val};
+       $priority = $itm->{'^'};
+    }
     $t = "" if not defined $t;
     if($t eq 'CONST' or $t eq 'CONSTANT'){#Single constant with mulit-line value;
         # It is NOT allowed to overwrite constant.
@@ -445,7 +465,7 @@ sub doInstruction { my ($self,$e,$t,$v) = @_;
     }
     elsif($t eq 'VAR' or $t eq 'VARIABLE'){
         $v =~ s/^\s//;
-        $ANONS->{$e} = $v;
+        $anechoic->{$e} = $v;
     }
     elsif($t eq 'DATA'){
           $self->doDATAInstructions_($e,$v)
@@ -463,7 +483,7 @@ sub doInstruction { my ($self,$e,$t,$v) = @_;
         if($isMetaConst){
             $self ->{$e} = $v
         }else{
-            $ANONS->{$e} = $v
+            $anechoic->{$e} = $v
         }
     }elsif($t eq 'FILE'){#@TODO Test case this
         $self->doLoadDataFile($e,$v);
@@ -475,7 +495,7 @@ sub doInstruction { my ($self,$e,$t,$v) = @_;
             if ($isMetaConst){
                 $self -> {$e} = $v;
             }else{
-                $ANONS = $v
+                $anechoic = $v
             }
         }
         my $prc_last  = ($v =~ s/($meta_process_last)/""/ei)?1:0;
@@ -486,9 +506,9 @@ sub doInstruction { my ($self,$e,$t,$v) = @_;
         $includes[@includes] = {script=>$v,local=>$CUR_SCRIPT,loaded=>0, prc_last=>$prc_last};
     }elsif($t eq 'TREE'){
         my  $tree = 0;
-        if (!$v){
-                $v = $e;
-                $e = 'LAST_DO';
+        if( !$v ){
+             $v = $e;
+             $e = CNFMeta::ANN();
         }
         if( $v =~ s/($meta_has_priority)/""/ei ){
             $priority = 1;
@@ -496,9 +516,9 @@ sub doInstruction { my ($self,$e,$t,$v) = @_;
         if( $v =~ s/$meta_priority/""/sexi ){
             $priority = $2;
         }
-            $tree = CNFNode->new({'_'=>$e,'~'=>$v,'^'=>$priority});
-            $tree->{DEBUG} = 1 if $self->{DEBUG};
-            $instructs{$e} = \$tree;
+        $tree = CNFNode->new({'_'=>$e,'~'=>$v,'^'=>$priority});
+        $tree->{DEBUG} = 1 if $self->{DEBUG};
+        $instructs{$e} = \$tree;
     }elsif($t eq 'TABLE'){           # This all have now be late bound and send via the CNFSQL package. since v.2.6
                                      # It is hardly been used. But in the future this might change.
         my $type = "NONE"; if ($v =~ 'AUTOINCREMENT'){$type = "AUTOINCREMENT"}
@@ -513,7 +533,7 @@ sub doInstruction { my ($self,$e,$t,$v) = @_;
             my $ret;
             if (!$v){
                  $v = $e;
-                 $e = 'LAST_DO';
+                 $e = CNFMeta::ANN();
             }
             if( $v =~ s/($meta_has_priority)/""/ei ){
                 $priority = 1;
@@ -522,7 +542,7 @@ sub doInstruction { my ($self,$e,$t,$v) = @_;
                 $priority = $2;
             }
             if( $v=~ s/($meta_on_demand)/""/ei ){
-               $ANONS->{$e} = CNFNode -> new({'_'=>$e,'&'=>$v,'^'=>$priority});
+               $anechoic->{$e} = CNFNode -> new({'_'=>$e,'&'=>$v,'^'=>$priority});
                return;
             }
             ## no critic BuiltinFunctions::ProhibitStringyEval
@@ -530,10 +550,10 @@ sub doInstruction { my ($self,$e,$t,$v) = @_;
             ## use critic
              if ($ret){
                  chomp $ret;
-                 $ANONS->{$e} = $ret;
+                 $anechoic->{$e} = $ret;
              }else{
                  $self->warn("Perl DO_ENABLED script evaluation failed to evalute: $e Error: $@");
-                 $ANONS->{$e} = '<<ERROR>>';
+                 $anechoic->{$e} = '<<ERROR>>';
              }
         }else{
             $self->warn("DO_ENABLED is set to false to process property: $e\n")
@@ -548,14 +568,14 @@ sub doInstruction { my ($self,$e,$t,$v) = @_;
                 use Module::Load;
                 autoload $v;
                 $v =~ s/^(.*\/)*|(\..*)$//g;
-                $ANONS->{$e} = $v;
+                $anechoic->{$e} = $v;
             }catch{
                     $self->warn("Module DO_ENABLED library failed to load: $v\n");
-                    $ANONS->{$e} = '<<ERROR>>'
+                    $anechoic->{$e} = '<<ERROR>>'
             }
         }else{
             $self->warn("DO_ENABLED is set to false to process a LIB property: $e\n");
-            $ANONS->{$e} = '<<ERROR>>';
+            $anechoic->{$e} = '<<ERROR>>';
         }
     }
     elsif($t eq 'PLUGIN'){
@@ -590,14 +610,14 @@ sub doInstruction { my ($self,$e,$t,$v) = @_;
         #Register application statement as either an anonymous one. Or since v.1.2 a listing type tag.
         if($e !~ /\$\$$/){ #<- It is not matching {name}$$ here.
             if($self->{'HAS_EXTENSIONS'}){
-                $ANONS->{$e} = InstructedDataItem->new($e,$t,$v)
+               $anechoic->{$e} = InstructedDataItem->new($e,$t,$v)
             }else{
-                $v = $t if not $v;
-                if($e=~/^\$/){
-                    $self->{$e}  = $v if !$self->{$e}; # Not allowed to overwrite constant.
-                }else{
-                    $ANONS->{$e} = $v
-                }
+               $v = $t if not $v;
+               if($e=~/^\$/){
+                  $self->{$e}  = $v if !$self->{$e}; # Not allowed to overwrite constant.
+               }else{
+                  $anechoic->{$e} = $v
+               }
             }
         }
         else{
@@ -642,11 +662,11 @@ sub loadDataFile {  my ($self,$e,$path,$v,$i)=@_;
                         $tag = $kv[1];
                         $i = index $tag, "\n";
                         if($i==-1){
-                            $tag = $v = substr $tag, 0, (rindex $tag, ">>");
+                           $tag = $v = substr $tag, 0, (rindex $tag, ">>");
                         }
                         else{
-                            $v = substr $tag, $i+1, (rindex $tag, ">>")-($i+1);
-                            $tag = substr $tag, 0, $i;
+                           $v = substr $tag, $i+1, (rindex $tag, ">>")-($i+1);
+                           $tag = substr $tag, 0, $i;
                         }
                         if($tag eq 'DATA'){
                            $self->doDATAInstructions_($e,$v)
@@ -657,8 +677,8 @@ sub loadDataFile {  my ($self,$e,$path,$v,$i)=@_;
         }
 }
 ##
-# DATA instructions are not preserved as CNF script values as would be redundand and a waist.
-# They by default are only META translated into tables for efficiancy by data property name.
+# DATA instructions are not preserved as CNF script values as would be redundant and a waist.
+# They by default are only META translated into tables for efficiency by data property name.
 #private
 sub doDATAInstructions_{ my ($self,$e,$v,$t,$d)=@_;
         my $add_as_SQLTable = $v =~ s/${meta('SQL_TABLE')}/""/sexi;
@@ -670,10 +690,10 @@ sub doDATAInstructions_{ my ($self,$e,$v,$t,$d)=@_;
         my @hdr; my @rows; my $autonumber = 0;
         my $ref = $self->{__DATA__}{$e};
         if($ref){
-            $ref = $$ref;
-            @hdr = @{$ref->{header}};
-            @rows= @{$ref->{data}};
-            $autonumber = $ref->{auto}; $isAutonumber = 1 if($autonumber || $isAutonumber);
+           $ref = $$ref;
+           @hdr = @{$ref->{header}};
+           @rows= @{$ref->{data}};
+           $autonumber = $ref->{auto}; $isAutonumber = 1 if($autonumber || $isAutonumber);
         }
         $v=~ s/^\s*//gm;
         foreach my $row(split(/~\s/,$v)){
@@ -746,11 +766,7 @@ sub doDATAInstructions_{ my ($self,$e,$v,$t,$d)=@_;
 sub parse {  my ($self, $cnf_file, $content, $del_keys) = @_;
 
     my @tags;
-    if($self->{'ANONS_ARE_PUBLIC'}){
-       $ANONS = \%ANONS;
-    }else{
-       $ANONS = $self->{'__ANONS__'};
-    }
+    $cnf_file = $cnf_file -> {path} if ref($cnf_file) eq 'CNFGlobalFile';
 
     # We control from here the constances, as we need to unlock them if a previous parse was run.
     unlock_hash(%$self);
@@ -787,7 +803,7 @@ sub parse {  my ($self, $cnf_file, $content, $del_keys) = @_;
     foreach my $tag (@tags){
          next if not $tag;
       next if $tag =~ m/^(>+)|^(<<)/;
-      if($tag =~ m/^<(\w*)\s+(.*?)>*$/gs){ # Original fastest and early format: <<<anon value>>>
+      if($tag =~ m/^<\s*(\w*)\s+(.*?)>*$/gs){ # Original fastest and early format: <<<anon value>>>
            my $t = $1;
            my $v = $2;
            if(isReservedWord($self, $t)){
@@ -802,7 +818,7 @@ sub parse {  my ($self, $cnf_file, $content, $del_keys) = @_;
                            $line = $3; $line =~ s/^\s*(['"])(.*)\g{1}$/$2/ if $line;#strip quotes
                         if(defined $name){
                             if($isVar && not $isMETAConst){
-                                 $ANONS ->{$name} = $line if $line
+                                 $anechoic ->{$name} = $line if $line
                             }else{
                                 $name =~ s/^\$// if $isMETAConst;
                                 # It is NOT allowed to overwrite a constant, so check an issue warning.
@@ -827,7 +843,7 @@ sub parse {  my ($self, $cnf_file, $content, $del_keys) = @_;
                   $t = $1;
                   $v = $2;
               }
-              $ANONS->{$t} = $v;
+              $anechoic->{$t} = $v;
            }
 
         }else{
@@ -836,11 +852,11 @@ sub parse {  my ($self, $cnf_file, $content, $del_keys) = @_;
             # Check if very old format and don't parse the data for old code compatibility to (still) do it.
             # This is interesting, as a newer format file is expected to use the DATA instruction and final data specified script rules.
             if($CNF_VER eq 'CNF2.2' && $tag =~ m/(\w+)\s*(<\d+>\s)\s*(.*\n)/mg){#It is old DATA format annon
-                  $e = $1;
-                  $t = $2;
-                  $v = substr($tag,length($e)+length($t));
-                  $ANONS->{$e} = $v;
-                  next;
+               $e = $1;
+               $t = $2;
+               $v = substr($tag,length($e)+length($t));
+               $anechoic->{$e} = $v;
+               next;
             }
             # Before mauling into possible value types, let us go for the full expected tag specs first:
             # <<{$sig}{name}<{INSTRUCTION}>{value\n...value\n}>>
@@ -858,13 +874,13 @@ sub parse {  my ($self, $cnf_file, $content, $del_keys) = @_;
                 }
             }else{
                                                 #############################################################################
-                $tag =~ m/\s*([@%\$\.\/\w]+)\s* # The name.
-                                ([ <>\n])       # begin or close of instruction, where '\n' mark in script as instruction less.
-                                ([^<^>^^\n]+)   # instruction or value of anything
-                                    ([<>\n]?)   # close mark for instruction or is less if \n encountered before.
+                $tag =~ m/\s*([@%\$\w\/\.]+)\s* # The name.
+                                ([ <>\n]*)?     # begin or close of instruction, where '\n' mark in script as instruction less.
+                                ([^<>\n]+)      # instruction or value of anything
+                                ([ <>\n])?      # close mark for instruction or is less if \n encountered before.
                                     (.*)        # actual value is the rest.
                                        (>$)*    # capture above value up to here from buffer, i.e. if coming from a >>> tag.
-                         /gmxs;                 ###############################################################################
+                         /gmsx;                 ###############################################################################
 
                 $e =$1;
                 if($e eq '@' or $2 eq '<' or ($2 eq '>' and !$4)){
@@ -891,9 +907,9 @@ sub parse {  my ($self, $cnf_file, $content, $del_keys) = @_;
                    @array = @{$lists{$e}};
                 }
                 if(!$t or $t ne 'DATA'){
-                    push @array, InstructedDataItem -> new($e, $t, $v);
-                    $lists{$e} = \@array;
-                    next;
+                   push @array, InstructedDataItem -> new($e, $t, $v);
+                   $lists{$e} = \@array;
+                   next;
                 }
             }elsif ($e eq '@'){#collection processing.
                 my $isArray = $t=~ m/^@/;
@@ -925,10 +941,10 @@ sub parse {  my ($self, $cnf_file, $content, $del_keys) = @_;
                     my $macro = 0;
                     if(exists($properties{$t})){
                         if($self->isReservedWord($t)){
-                            $self->warn("Skipped a try to overwrite a reserved property -> $t.");
-                            next
+                           $self->warn("Skipped a try to overwrite a reserved property -> $t.");
+                           next
                         }else{
-                            %hsh =  %{$properties{$t}}
+                           %hsh =  %{$properties{$t}}
                         }
                     }else{
                        %hsh =();
@@ -950,7 +966,7 @@ sub parse {  my ($self, $cnf_file, $content, $del_keys) = @_;
                                 my @arr = ($value =~ m/(\$\$\$.+?\$\$\$)/gm);
                                 foreach my $find(@arr) {
                                     my $s = $find; $s =~ s/^\$\$\$|\$\$\$$//g;
-                                    my $r = $ANONS->{$s};
+                                    my $r = $anechoic->{$s};
                                     $r = $self->{$s} if !$r;
                                     $r = $instructs{$s} if !$r;
                                     CNFParserException->throw(error=>"Unable to find property for $t.$name -> $find\n",show_trace=>1) if !$r;
@@ -976,11 +992,10 @@ sub parse {  my ($self, $cnf_file, $content, $del_keys) = @_;
     }
     # Do those autonumbering list anons, and for pre instruction processing prepare if have it.
     if(%lists){
-       foreach my $arr(values %lists){
-            foreach my $item(@$arr){
-                my $e = $item->{ele} .   $item ->{aid};
-                doInstruction($self, $e, $item->{ins},$item->{val});
-            }
+       foreach my $arr(values %lists){                        
+          foreach my $itm(@$arr){                
+             doInstruction($self, $itm);
+          }
        }
        undef %InstructedDataItem::counters;
     }
@@ -989,18 +1004,18 @@ sub parse {  my ($self, $cnf_file, $content, $del_keys) = @_;
     if(%instructs && not $IS_IN_INCLUDE_MODE){
         my @items;
         foreach my $e(keys %instructs){
-            my $struct = $instructs{$e};
-            my $type =  ref($struct);
+            my $struct   = $instructs{$e};
+            my $type     =  ref($struct);
             if ($type eq 'REF'){
                 $struct  = $$struct;
-                $type =  ref($struct);
+                $type    =  ref($struct);
             }
             if($type eq 'String'){
-                my $v = $struct;
+                my $v   = $struct;
                 my @arr = ($v =~ m/(\$\$\$.+?\$\$\$)/gm);
                 foreach my $find(@arr) {# <- MACRO TAG translate. ->
                         my $s= $find; $s =~ s/^\$\$\$|\$\$\$$//g;#
-                        my $r = %$ANONS{$s};
+                        my $r = %$anechoic{$s};
                         $r = $self->{$s} if !$r;
                         if(!$r){
                             $self->warn("Unable to find property to translate macro expansion: $e -> $find\n");
@@ -1008,7 +1023,7 @@ sub parse {  my ($self, $cnf_file, $content, $del_keys) = @_;
                             $v =~ s/\Q$find\E/$r/g;
                         }
                 }
-                $ANONS->{$e}=$v;
+                $anechoic->{$e}=$v;
             }else{
                 $items[@items] = $struct;
             }
@@ -1021,7 +1036,14 @@ sub parse {  my ($self, $cnf_file, $content, $del_keys) = @_;
             my $type =  ref($struct);
             if($type eq 'CNFNode' && $struct-> priority() > 0){
                $struct->validate() if $self->{ENABLE_WARNINGS};
-               $ANONS ->{$struct->name()} = $struct->process($self, $struct->script());
+               if($struct->name() eq CNFMeta::ANN()){
+                  my $anode = $struct->process($self, $struct->script());
+                  foreach my $node($$anode->nodes()){
+                       $anechoic ->{$node->name()} = \$node;
+                  }
+               }else{
+                  $anechoic ->{$struct->name()} = $struct->process($self, $struct->script());
+               }
                splice @items, $idx, 1
             }
         }
@@ -1031,7 +1053,7 @@ sub parse {  my ($self, $cnf_file, $content, $del_keys) = @_;
             my $type =  ref($struct);
             if($type eq 'CNFNode'){
                $struct->validate() if $self->{ENABLE_WARNINGS};
-               $ANONS->{$struct->name()} = $struct->process($self, $struct->script());
+               $anechoic->{$struct->name()} = $struct->process($self, $struct->script());
             }elsif($type eq 'InstructedDataItem'){
                 my $t = $struct->{ins};
                 if($t eq 'PLUGIN'){
@@ -1380,7 +1402,7 @@ sub writeOut { my ($self, $handle, $property) = @_;
         return 1;
     }
     else{
-      $prp = $ANONS{$property};
+      $prp = $anechoic->{$property};
       $prp = $self->{$property} if !$prp;
       if (!$prp){
          $buffer = "<<ERROR<$property>Property not found!>>>\n"
@@ -1417,11 +1439,11 @@ sub log {
 
     $message = "$type $message" if $isWarning;
     if($message =~ /^ERROR/ || ($isWarning && $self->{ENABLE_WARNINGS})){
-        $message =~ s/(\s+line\s)(\d+)\.*\s+/:$2\n/gm;
-        warn  $time . " " .$message;
+       $message =~ s/(\s+line\s)(\d+)\.*\s+/:$2\n/gm;
+       warn  $time . " " .$message;
     }
     elsif(%log && $log{console}){
-        print $time . " " .$message ."\n"
+       print $time . " " .$message ."\n"
     }
     if(%log && _isTrue($log{enabled}) && $message){
         my $dir      = $log{directory}; $dir = '.' if not $dir; $dir .= '/' if $dir !~ /\/$/;
@@ -1501,8 +1523,8 @@ sub  JSON {
 }
 
 ###
-# CNFNodes are kept as anons by the TREE instruction, but these either could have been futher processed or
-# externaly assigned too as nodes to the parser.
+# CNFNodes are kept as anons by the TREE instruction, but these either could have been further processed or
+# externally assigned too as nodes to the parser.
 ###
 our %NODES;
 sub addTree {
@@ -1511,7 +1533,7 @@ sub addTree {
         $NODES{$name} = $node;
     }
 }
-### Utility way to obtain CNFNodes from a configuration.
+### Utility way to obtain CNFNodes from an configuration.
 sub getTree {
     my ($self, $name) = @_;
     return $NODES{$name} if exists $NODES{$name};
@@ -1519,10 +1541,10 @@ sub getTree {
     if(ref($ret) eq 'CNFNode'){
         return \$ret;
     }
-    return;
+    return $ret
 }
 ##
-# Conveniently ribs an cnf file for an pl source file to be next too in marriage.
+# Conveniently ribs an cnf file for an pl source file to be next to in marriage.
 # Ribs means the config file is same name next to it.
 # @$const - Dynamic instance assignable hash with constances, optional can be undef.
 # @$file  - Path to CNF file if missing will be created.