Autor Téma: Návrh typu pro regex - problém s vnořením do sebe sama  (Přečteno 892 krát)

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 676
  • Karma: 41
    • Verze Delphi: 10.3
Re:Návrh typu pro regex - problém s vnořením do sebe sama
« Odpověď #15 kdy: 11-06-2019, 21:36:18 »
Možná jsem to přehlídnul, ale jak je vlastně deklarovaný Assertions? :-)
Jinak "len" možná ani nepotřebuješ ukládat, pokud teda ve Tvé verzi Delphi taky už funguje length(Assertions.secs);

Offline vangog

  • Hrdina
  • ****
  • Příspěvků: 347
  • Karma: 0
    • Verze Delphi: 7
Re:Návrh typu pro regex - problém s vnořením do sebe sama
« Odpověď #16 kdy: 12-06-2019, 08:20:37 »
Assertions to celé zabaluje a je členem třídy.

type TRegex_assertions = record
  on: boolean;
  isBefore: boolean;
  isAfter:  boolean;
  len: byte;  // length of the sections
  secs: Array of TRegex_sec;
end;


Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 676
  • Karma: 41
    • Verze Delphi: 10.3
Re:Návrh typu pro regex - problém s vnořením do sebe sama
« Odpověď #17 kdy: 12-06-2019, 08:41:17 »
Excellent
Rated 1 time
Jo, tady máš secs: Array of TRegex_sec; tj. stačí opravdu setlength, protože prvky pole jsou přímo ty záznamy a ne ukazatele.

Offline vangog

  • Hrdina
  • ****
  • Příspěvků: 347
  • Karma: 0
    • Verze Delphi: 7
Re:Návrh typu pro regex - problém s vnořením do sebe sama
« Odpověď #18 kdy: 12-06-2019, 10:17:53 »
Ještě bych potřeboval poradit. Teď jsem si uvědomil, že budu potřebovat pracovat s pointerama, abych se k sekcím dostal dynamicky. Takže potřebuju napsat funkci, která vrátí pointer.

Jak ale takovou funkci nadeklarovat?

Co chci použít je:
var pSection: ^pTRegex_sec;
pSection := getCurrentSectionPointer();
incSection(false, pSection); // zavedení první sekce

A teď vysím u té deklarace:
Kód: Delphi [Vybrat]
  1. function getCurrentSectionPointer(): ???;

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 676
  • Karma: 41
    • Verze Delphi: 10.3
Re:Návrh typu pro regex - problém s vnořením do sebe sama
« Odpověď #19 kdy: 12-06-2019, 10:22:47 »
Ještě bych potřeboval poradit. Teď jsem si uvědomil, že budu potřebovat pracovat s pointerama, abych se k sekcím dostal dynamicky. Takže potřebuju napsat funkci, která vrátí pointer.

Jak ale takovou funkci nadeklarovat?

Co chci použít je:
var pSection: ^pTRegex_sec;
pSection := getCurrentSectionPointer();
incSection(false, pSection); // zavedení první sekce

A teď vysím u té deklarace:
Kód: Delphi [Vybrat]
  1. function getCurrentSectionPointer(): ???;

var pSection: ^pTRegex_sec je asi špatně;
TRegex_sec je záznam
pTRegex_sec je ukazatel na ten záznam
^pTRegex_sec je ukazatel na ukazatel na záznam, to pravděpodobně nepotřebuješ

function getCurrentSectionPointer(): pTRegex_sec  ? (vrací ukazatel na záznam)

Offline vangog

  • Hrdina
  • ****
  • Příspěvků: 347
  • Karma: 0
    • Verze Delphi: 7
Re:Návrh typu pro regex - problém s vnořením do sebe sama
« Odpověď #20 kdy: 12-06-2019, 10:44:28 »
EDIT 1

Co jsem zatím vymyslel (ale ještě nefunkční):

Kód: Delphi [Vybrat]
  1. procedure TTrackerRegex.incSection(newLevel: boolean; pSec: PTRegex_sec; pPrevLevSec: PTRegex_sec = nil);
  2. begin
  3.   if (false) then
  4.     begin
  5.       info.sec := Assertions.len;
  6.       setlength(Assertions.secs, Assertions.len+1);
  7.       Inc(Assertions.len);
  8.     end
  9.   else
  10.     begin // CREATE NEW LEVEL INTO CURRENT SECTION
  11.       setlength(pSec.secs, pPrevLevSec.len+1);
  12.       Inc(pPrevLevSec.len);
  13.       Inc(info.sec_level);
  14.     end;
  15. //  info.sec_levels[] // zápis úrovní pøístupu k aktuálnì zpracovávané sekci
  16. end;
  17.  

Kód: Delphi [Vybrat]
  1. function TTrackerRegex.getCurrentSectionPointer(): pTRegex_sec;
  2. begin
  3. end;
  4.  
Iniciace:
Kód: Delphi [Vybrat]
  1. pSection := getCurrentSectionPointer();
  2. incSection(false, pSection);
  3.  
« Poslední změna: 12-06-2019, 10:49:26 od vangog »

Offline vangog

  • Hrdina
  • ****
  • Příspěvků: 347
  • Karma: 0
    • Verze Delphi: 7
Re:Návrh typu pro regex - problém s vnořením do sebe sama
« Odpověď #21 kdy: 12-06-2019, 11:24:42 »
Jak napsat toto (tučná část), abych získal pointer?

function TTrackerRegex.getCurrentSectionPointer(pCurrentLevSec: PTRegex_sec = nil): pTRegex_sec;
begin
  if ( pCurrentLevSec = nil) then
    Result := Assertions.secs[info.sec]
  else
    Result := Assertions.secs[info.sec]
end;

Chyba:
Incompatible types: 'TRegex_sec' and 'pTRegex_sec'

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 676
  • Karma: 41
    • Verze Delphi: 10.3
Re:Návrh typu pro regex - problém s vnořením do sebe sama
« Odpověď #22 kdy: 12-06-2019, 11:26:06 »
Result := @Assertions.secs[info.sec]

Offline vangog

  • Hrdina
  • ****
  • Příspěvků: 347
  • Karma: 0
    • Verze Delphi: 7
Re:Návrh typu pro regex - problém s vnořením do sebe sama
« Odpověď #23 kdy: 12-06-2019, 11:37:37 »
Díky

Offline vangog

  • Hrdina
  • ****
  • Příspěvků: 347
  • Karma: 0
    • Verze Delphi: 7
Re:Návrh typu pro regex - problém s vnořením do sebe sama
« Odpověď #24 kdy: 14-06-2019, 18:28:06 »
Co dělám špatně?

Kód: Delphi [Vybrat]
  1.    TTrackerRegex = Class
  2.     private
  3.     Sections: pTRegex_sec; // wrapper
  4. ...
  5.  

Přidělení paměti:
Kód: Delphi [Vybrat]
  1. Sections := new(pTRegex_sec);
  2.  
V této části když to prohlédnu v kukátku ^Sections
vidím toto: #19
Co to znamená? Očekával jsem že uvidím tu výše nadeklarovanou strukturu pTRegex_sec.

destructor:
Kód: Delphi [Vybrat]
  1. Dispose(sections);
  2.  

Offline Delfin

  • Padawan
  • ******
  • Příspěvků: 1744
  • Karma: 67
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Návrh typu pro regex - problém s vnořením do sebe sama
« Odpověď #25 kdy: 14-06-2019, 19:01:26 »
V této části když to prohlédnu v kukátku ^Sections

Dereference pole Sections te tridy by se psala stylem Sections^, ne ^Sections.
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Offline vangog

  • Hrdina
  • ****
  • Příspěvků: 347
  • Karma: 0
    • Verze Delphi: 7
Re:Návrh typu pro regex - problém s vnořením do sebe sama
« Odpověď #26 kdy: 14-06-2019, 19:25:44 »
Dík, tak tohle se mi ještě plete.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2503
  • Karma: 131
    • Verze Delphi: D2007, XE3, DX10
Re:Návrh typu pro regex - problém s vnořením do sebe sama
« Odpověď #27 kdy: 14-06-2019, 22:29:34 »
Excellent
Rated 1 time

V této části když to prohlédnu v kukátku ^Sections
vidím toto: #19
Co to znamená?
Zajimave. To vypada, ze Delphi na urovni bubaku rozumi caret notation a ty jsi napsal ^S = Ctrl-S = #19

Offline Delfin

  • Padawan
  • ******
  • Příspěvků: 1744
  • Karma: 67
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Návrh typu pro regex - problém s vnořením do sebe sama
« Odpověď #28 kdy: 14-06-2019, 22:36:31 »
Zajimave. To vypada, ze Delphi na urovni bubaku rozumi caret notation a ty jsi napsal ^S = Ctrl-S = #19

Cekal bych, ze tomu nebude rozumet, kazdopadne protoze notace ^PointerVariable (tady jde o ^Sections) by sama o sobe nic znamenat nemohla (je pro notaci ukazatelu na datove typy ^DataType).
« Poslední změna: 15-06-2019, 08:12:24 od < z > »
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Offline vangog

  • Hrdina
  • ****
  • Příspěvků: 347
  • Karma: 0
    • Verze Delphi: 7
Re:Návrh typu pro regex - problém s vnořením do sebe sama
« Odpověď #29 kdy: 15-06-2019, 07:29:47 »
Nerozumím vám, musíte na mě polopaticky.

Každopádně ještě potřebuju poradit. Takže když používám setlength rekurzivně, musím to potom zase rekurzivně uvolnit z paměti, nebo se to uvolňuje samo?

Ptal jsem se předtím na stackoverflow na to jak mám nastavovat ten typ sekce a bylo mi řečeno, že první úroveň (wrapper) mmám nastavit tím setlength. A ty vnořené, že jim musím předělit paměť pomocí New. A teď když to realizuju a ladím tak se to asi potvrzuje, že to jinak nejde (ale sám nevím proč):

Kód: Delphi [Vybrat]
  1. procedure TTrackerRegex.incSection(newLevel: boolean; pSec: pTRegex_sec = nil);
  2. begin
  3.   if (pSec = nil ) then
  4.     begin
  5.       // A WRAPPER secs[0]
  6.       Sections := new(pTRegex_sec);
  7.       // The root section parent is self
  8.       Sections.parent := Sections;
  9.       Sections.len := 0;
  10.       Sections.hasSections := false;
  11.       Sections.hasUnits    := false;
  12.       exit;
  13.     end;
  14.   if (not newLevel) then
  15.     begin // EXPAND SECTION
  16.       setlength(psec.secs, psec.len+1);
  17.       psec.secs[psec.len].parent := psec.secs[psec.len];
  18.       Inc(psec.len);
  19.     end
  20.   else
  21.     begin // CREATE NEW LEVEL INTO CURRENT SECTION
  22.           pSec.hasSections := true;
  23.           setlength(psec.secs, psec.len+1);
  24.           Inc(psec.len);
  25.     end;
  26. end;

V té části, kde je // CREATE NEW LEVEL INTO CURRENT SECTION
Kód: Delphi [Vybrat]
  1. pSec.hasSections := true;
  2. setlength(psec.secs, psec.len+1);
  3.  
kukátko psec.secs ukazuje nil.

Takže sice nevím proč se nepřidělí paměť automaticky, ale rozumím, že musím přidělit paměť pomocí New. A při destruktoru rekurzivně zase deallokovat pomocí Dispose().