Attached is my use case which is parsing of PDF cross reference indices. There are normally three numeric entries per line. e.g.
xref 0 8 0000000000 65535 f 0000000009 00000 n 0000000074 00000 n 0000000120 00000 n Which populates nicely into an array of 'n' lines of shape 3. There's the rare, but possible case of an xref section with zero entries xref 0 0 (I've encountered real-world PDF's like this). The attached grammar/actions attempted to handle it as an array of shape [0;3], but wont work on current Rakudo. Just my preferred solution for the above case. - David On Sun, Aug 27, 2017 at 12:38 PM, Brandon Allbery via RT < perl6-bugs-follo...@perl.org> wrote: > > Well, what do you mean? Of course you can't put anything into it, and any > > attempt to index it will throw. It may seem useless, however, if you can > > have > > an empty array, why can't you have a shaped empty array? > > > > Only if all dimensions are unindexable. Otherwise you have something with > inaccessible slots (and, potentially thereby, not truly leaked but > unusable, memory). > > And an empty unshaped array, in addition to being usable as such > (degenerate case of all shaped dimensions being size 0), can be made > non-empty. Shaped arrays cannot. > >
grammar XRef { rule TOP { xref\n<xref-section>+ } rule xref-section {<obj-first-num=.int> <obj-count=.int>' '*\n<xref-entry>*} rule xref-entry {<byte-offset=.int> <gen-number=.int> <obj-status>' '?\n} token int { < + - >? \d+ } token obj-status:sym<free> {f} proto token obj-status {*} token obj-status:sym<inuse> {n} } class XRef::Actions { method TOP ($/) { my $xref = [ $<xref-section>>>.ast ]; make $xref; } method xref-section($/) { my uint $obj-count = $<obj-count>.ast.value; my uint $obj-first-num = $<obj-first-num>.ast.value; my @entries[$obj-count;3] = $<xref-entry>».ast.List; make { :$obj-first-num, :$obj-count, :@entries }; } method xref-entry($/) { my UInt @entry = $<byte-offset>.ast.value, $<gen-number>.ast.value, $<obj-status>.ast; make @entry; } method int($/) { make (:int($/.Int)); } method obj-status:sym<free>($/) { make 0 } method obj-status:sym<inuse>($/) { make 1 } } use Test; plan 2; my $xref-regular = "xref 0 8 0000000000 65535 f 0000000009 00000 n 0000000074 00000 n 0000000120 00000 n 0000000179 00000 n 0000000322 00000 n 0000000415 00000 n 0000000445 00000 n "; my $xref-empty = "xref 0 0 "; my $actions = XRef::Actions.new; lives-ok {XRef.parse($xref-regular, :$actions)}; lives-ok {XRef.parse($xref-empty, :$actions)};