Připomínám, že píšu v Delphi 7.
Pracuji teď na třídě, která má vytvářet regulární výrazy a později snad s nimi pracovat. Něco mám už napsané, ale teď jsem se dostal do kritického bodu, kdy se musím rozhodnout jestli budu pracovat jen s jednou úrovní předloh nebo s vícero. S jednou úrovní je to jednoduché.
Nejdříve terminologie, kterou jsem si pro třídu vytvořil.
Sekcí nazývám úsek regulárního výrazu:
a) celý výraz bez alternativ a vnořených předloh:
např. 'abc\w{1,3}'
b) sekce alternativ, příklad dvou úseků. 'ano|ne'
c) sekce s vnořenýma předlohama, příklad: '(ano|ne)/(ne|ano)'
Třídou znaku nazývám jakýkoliv zástupný znak, představující více znaků, např. \w, \s, \d
Pod to spadá, "klasická třída znaku": []
Jednotky obsahují buďto samostatné písmeno nebo zástupný znak reprezentovaný třídou.
(Tohle asi budu měnit, že by písmeno mohlo být zařazeno přímo pod sekcí).
Tak a teď ke kořenu problému. Návrh typu TRegex_sec pro jednu úroveň předloh:
type TRegex_sec = record
hasUnits: boolean;
units: Array of TRegex_unit;
len: word; // délka units
end;
V případě, že bych chtěl udělat víceúrovňové předlohy bych potřeboval něco podobného, což nelze nadefinovat:
type TRegex_sec = record
secs: Array of TRegex_secs;
secLen: byte; // length of the units
hasSections: boolean;
hasUnits: boolean;
units: Array of TRegex_unit;
unitsLen: byte; // length of the units
end;
Při parsování by to vypadalo tato:
předloha: 'a(b)|b(c)'
sec('a(b)')->sec('b');
sec('a(b)')->sec('b');
sec('b(c)')->sec('c');
nebo složitěji:
předloha: 'a(b|bc)|b(c|ab)'
sec('a(b|bc)')->sec('b|bc')->sec('b');
sec('a(b|bc)')->sec('b|bc')->sec('c');
sec('b(c|ab)')->sec('c|ab')->sec('c');
sec('b(c|ab)')->sec('c|ab')->sec('ab');
takto by se dalo postupovat víc a víc do hloubky, ale jak vidíte při definici je problém v tom jak v definici typu použít něco co ještě nebylo nadefinováno... Totiž jakýsi odkaz na sebe sama.
type
TRegex_sec = record
secs: Array of
TRegex_secs;
end;