empty/0
.
Situace zde bude jen nepatrně složitější.
Nejdříve si uveďme formální definici množiny FIRST:
Definice:
Pro větnou formu v bezkontextové gramatice G=(N,T,P,S) platí:
Množina obsahuje všechny terminální symboly, které se mohou vyskytnout na začátku řetězců derivovaných z . Jestliže lze z derivovat také prázdný řetězec, pak jej množina FIRST obsahuje rovněž.Množinu FIRST budeme používat při rozhodování, který z parserů v alternativní kompozici vybrat. Její výpočet budeme provádět společně s určením schopnosti přijímat prázdný řetězec v módu
eFirst/0
, jenž
bude místo seznamu úspěšných rozkladů vydávat strukturu:
Navíc je připraven mód
first/0
, který využívá eFirst/0
a vydává pouze množinu FIRST.
FIRST nebude reprezentována výčtem výhledů, ale
seznamem podmínek, které budou dostatečně přesně vymezovat její rozsah.
Ukažme si nejprve rozšíření definic základních primitiv:
epsilon(first+[]). return(_,first+[]). terminate(first+[]).Primitivum
item
přijímá ze vstupního textu libovolnou položku:item(first+[pcTrue]).Parser terminálních symbolů
symbol
už může použít implicitní cestu
výpočtu:fulfil(C,first+[C]). symbol(S,I+FIRST):- fulfil(==(S),I+FIRST).FIRST sekvenční kompozice a je tvořena množinou FIRST(). Pokud navíc přijímá prázdný řetězec je sjednocením množin FIRST() a FIRST():
<&>(P1,P2,eFirst+eFirst(Empty,FIRST)):- eFirst+eFirst(Empty1,FIRST1) :-> P1, (Empty1=true -> first+FIRST2 :-> P2 ; FIRST2=[]), append(FIRST1,FIRST2,FIRST), <&>(P1,P2,empty+Empty). <&>(P1,P2,first+FIRST):- <&>(P1,P2,eFirst+eFirst(_,FIRST)).Množina FIRST alternativní kompozice parserů a je vždy sjednocením množin FIRST() a FIRST():
<:>(P1,P2,first+L):- first+L1 :-> P1, first+L2 :-> P2, append(L1,L2,L).Jako příklad si ukážeme parser
double
v módu first/0
:?- first+L :-> double. L = [lElementOf("-0123456789"])] YesTaké pro tyto módy jsou připraveny predikáty , jako
invokeEmpty
a invokeFIRST
.
dvorka 2013-12-31