VilleKrumlinde / dcocor

Coco/R parser generator for Delphi
Other
23 stars 8 forks source link

Probable BUG in CharSets.TCharSet SubtractRangePtr #3

Open Nico55-vd opened 2 months ago

Nico55-vd commented 2 months ago

Apparently that procedure does not coreectly subtract a TCharSet from self resulting in an inverted range bounds that may cause an error in FPC. Could someone confirm this using the joined CharSets unit, and the limited test grammar joined here.

eol = CHR(13) . Special = '"' + "%&'()*+,-./:;<=>?|". Digit = "0123456789" . Letter = CHR(33)..CHR(127) - Special - Digit . /* CocoDelphi accepts CHR(255) */
Causes Subtract "#33,35-36,48-57,64-123,125-127" and "48-57" ->"#33,35-36,58-47,125-127" ERROR : from > To Range : 58 <= 47. where 58-47 is an inverted range that is likely to generate some troubles, maybe the one mentioned in https://github.com/VilleKrumlinde/dcocor/issues/2)

Joined RangeUnionBug.atg and modified CharSets. Note that the CharSets contains embryos of further development and should not impact the described error.

atg.zip

VilleKrumlinde commented 2 months ago

I can confirm this happening here too.

Please try modifying it like this. That gets rid of the problem here but I'm not sure it is correct.

procedure TCharSet.SubtractRangePtr(aPtr: Pointer);
var ar,r: TRange;
    I,M: Integer;
begin
  ar.ptr := aPtr;
  I := 0;
  while I<fList.Count do
  with r do
  begin
    ptr := fList[I];
    if from_>ar.to_ then Exit;

    if to_>=ar.from_ then
    begin
      if from_>=ar.from_ then
         from_ := ar.to_+1;
      if to_<=ar.to_ then
         to_ := ar.from_-1;
      if from_>to_ then
      begin
        fList.Delete(I);
        Continue;
      end
      else if from_>ar.to_ then
      begin
        fList[I] := ptr; Exit;
      end;
      if to_<ar.from_ then
      begin
        fList[I] := ptr; Inc(I);
      end else begin
        M := to_;
        to_ := ar.from_-1;
        fList.Insert(I,ptr);
        from_ := ar.to_+1;
        to_ := M;
        fLIst[I+1] := ptr;
        Exit;
      end;
    end else Inc(I);
  end;
end;
Nico55-vd commented 2 months ago

Looks like it works. Difficult to judge if it covers everything, time will tell.

Funnily, I'm playing with that TCharSet with a few new and different strategies for Set Operations methods and have, ;-), a problem with that same sub-range matching an exact same sub-range. Life is fun...