=?us-ascii:iso-8859-2:utf-8?Q?=5Bnem-p?= =?us-ascii:iso-8859-2:utf-8?Q?l=5D_Dalej_o_sk=B3adni_rozszerze=F1?=

Lukasz Kaiser kaiser at tenet.pl
Mon Nov 3 17:25:27 CET 2003


Hej.
 
> Na pocz±tek proponujê zmianê [< >] na <[ ]>, bo ³adniej i czytelniej wygl±da 
> (a i tak jest tymczasowe, mo¿e wymy¶limy co¶ lepszego).

Mysle, zebys sprawdzil te konfilikty s/r i zeby sie na cos zdecydowac i
juz nie zmieniac, estetyka tych 2 krzaczkow nie ma chyba az takiego
znaczenia przynajmniej dopoki to nie jest uzywane przez > 5 osob.
 
> Taki sposób okre¶lania typu trzyma siê kupy. Ale rzeczywi¶cie bêdzie pewnie 
> potrzebnych kilka kolejnych typów, chyba ¿e np. definicje funkcji, klasy 
> podpi±æ pod wyrazenie.

Zobaczymy co bedzie potrzebne.
 
> Nie rozumiem co chcesz z tym $ robiæ. Ja my¶la³em o nim jako metodzie 
> wy³uskania informacji z atomowych wyra¿eñ/typów. Mo¿na np. napisaæ
> <[ x $(name, type) <- val ]>
> albo mo¿e nawet wprowadziæ konstruktory do ¶rodka
> <[ x $(Var(name), type) <- val $(Const(value), type) ]>
> gdzie
> x - matchuje siê do poddrzewa, w tym wypadku zawieraj±cego zmienn±
> name - do nazwy zmiennej
> type - do drzewa typu
> value - do wartosci (o ile 'val' nie jest wyrazeniem ani zmienna) o typie 
> 'type'. Problem je¶li ten typ to co¶ skomplikowanego, zdefiniowanego gdzie 
> indziej... to wymaga³oby znajomo¶ci tej definicji i otypowania wyra¿enia, 
> chyba ¿eby te typy tutaj traktowaæ jak w jêzyku skryptowym tudzie¿ w Prologu, 
> to znaczy jako parê t = 'nazwa konstruktora' * list t.

Nie, nie, nie. Definicja jest prosta.
Po pierwsze zakladamy ze kazda regula gramatyki jest w dwoch wersjach,
obecnej oraz B, czyli jest expr i Bexpr itd., oczywiscie wszystkie
rekurencyjne wywolania z Bexpr ida do Bexpr lub Bcosinnego.

Robimy:
pattern := ID 
 | qid [pattern]
 | _
 | {  ID  =  pattern  {  ;  ID  =  pattern  }  [  ;  ]  }
 | tuple_pattern
 | ( pattern )
 | [< code_pattern >] (* nowe *) // lub <[ lub inne krzaki

code_pattern := expr_code_p | ty_code_p | ... <- potrzebne typy

Dalej zmieniamy tak:
Bexpr := ... (*to co jest +*) | $(expr)

Teraz trzeba z takiego rozszerzonego drzewa skladniowego wygenerowac
zwykle, co sie robi tak, ze 
gen E_Bexpr ( ... ) -> E_pattern ( E_expr ( gen ... ) )
gen x -> x (zeby zostawic to co bylo w $() tak jak jest)
Oczywiscie to trzeba napisac dokladniej.
 
> Oczywi¶cie to moje zadanie i zajmê siê nim, kiedy ju¿ wymy¶limy w miarê 
> dok³adnie sk³adniê tego wszystkiego.

Skladnia jest chyba prosta w momencie jak zadasz gramatyke. Problem moze
byc z odzyskiwaniem typow, ale to jest trudny problem (patrz dalej).
 
> No i w³a¶nie tutaj napotka³em na kilka w±tpliwo¶ci:
> wywo³ania rekurencyjne oczywi¶cie chcemy, s± dwie propozycje
> -  ext f (a : syntax_tree ) : syntax_tree =
>     match a with [
>       | <[ x <- y + z ]> -> <[ x <- $f(y) - $f(z) ]>
>       ...
>      lub inna wersja takiego zmieszania metajêzyka z jêzykiem
> -  ext f (a : syntax_tree ) : syntax_tree =
>     match a with [
>       | <[ x <- y + z ]> -> def (ny, nz) = (f y, f z);
>                                     <[ x <- ny - nz ]>

Nie, pierwsza wersja zdecydowanie, w drugiej to niby czym ma sie roznic
ten x na poczatku od tego nx potem ? Mysle, ze to jest za trudne i wcale
nie jest jasne.
     
> Druga oczywi¶cie ³adniej wygl±da i w ogóle jest przejrzysta, ale jest 
> przyd³ugawa i nieco uci±¿liwa.

Przejrzysta ? Jak to sie zrobi minimalnie dluzsze to nie bedziesz nigdy
wiedzial czy matchujesz "x" z kodu czy swoja zmienna x. Metajezyk od
jezyka trzeba oddzielic.
 
> Kolejna sprawa to matchowanie list wyra¿eñ/typów. 
> <[ class x { contents } ]> -> ... tutaj 'contents' zmatchuje siê z list± 
> pól/metod. Pytanie czy dopuszczamy konstrukcjê bezpo¶retnio operujace w 
> ¶rodku:
> <[ class x { var1 : string; contentsrest } ]> -> ... niby bez sensu bo i tak 
> musimy t± resztê przerobiæ osobno, ale kto wie.

Nie, samo "contents" matchuje sie ze slowem "contents" w kodzie. Mozesz
napisac class x { $( c ) } i wtedy c jest odpowiedniego typu, czyli jest
lista wyrazen. Nie widze problemu z "class { var1 : string ; $(c) }", poza
tym ze "pattern match not exhaustive".
 
> No i potem te listy bêdzie siê sk³adaæ z powrotem
> <[ var1: int ]> :: rest -> <[ var1 : float ]> :: (f rest)

To jest OK.

> lub
> ... -> def ncontents = g contents;
>         <[ class x { costam; costam1; ncontents } ]>

Nie, <[ class x { costam; costam1; $(ncontents) } ]> lub po prostu
<[ class x { costam; costam1; $( g ( contents ) ) } ]>

> W sumie my¶lê, ¿e oba sposoby s± dobre i nie k³óc± siê, wiêc niech zostan±, a 
> w razie czego to komentujcie.

Nie, proba nie oddzielania jezyka od metajezyka skonczy sie tragicznie
zarowno dla czytelnosci jak i dla proby implementacji, to nie jest dobra
metoda.
 
> Chyba nie bêd± potrzebne, je¶li zrobimy tak jak pisa³em, ¿eby typy by³y 
> jakimi¶ stringami czy co¶ w tym stylu.

To nie bedzie takie proste z typami, ale z innych powodow. My bysmy
chcieli zeby w tym wzorcu ktory dostaniemy po zamianie [< ... >] znajdowal
sie juz kod z typami, czyli typedtree a nie tylko parsedtree (np. zeby nie
musiec robic inferencji typow). Ale to wyglada na zupelnie niewykonalne,
przynajmniej ja nie mam zadnego pomyslu jak to zrobic w tej chwili. To
znaczy zeby to zrobic to trzeba by cale typowanie przerobic zeby dzialalo
na drzewach skladniowych zawierajacych B-gramatyke, to bedzie troche
roboty. Moze zamienic na poczatek to B na jakis atrybut w typie i miec
przynajmniej to samo tylko przypadki dopisac ? Nie wiem, to juz nie jest
problem skladniowy.
 
> Chcia³bym zauwa¿yæ, ¿e dla mnie parsowanie tych rozszerzeñ wcala nie jest 
> jeszcze proste. Nie ma ustalonej sk³adni/semantyki $. 

To zalezy co znaczy ustalona ;). Ale ja mam ja dobrze zdefiniowana.

> Nie wiem jakiej postaci 
> bêd± funkcje i pola obiektów:
> <[ class _ { $(Var(name), type) }
> czy mo¿e
> <[ class _ { $(Field(name)) : type }
> i
> <[ class _ { 'a $(Fun(name)) (params) : type } - tu szczególnie w±tpliwa jest 
> zmienna typowa, bo ona wp³ywa mocno na parametry... a my by¶my tu rozwalili 
> to po³±czenie.

Hmm, po pierwsze jesli chcesz cokolwiek co nie jest stalym elementem
wzorca to pisz $( cokolwiek ). Masz wtedy
<[ class $(classname) { $(varname) : $(typename) } >]
dalej nie chcemy pisac zadnych konstruktorow, chociaz za $ wolno wpisac
kazde wyr. Nemerle odpowiedniego typu, wiec konstr. tez. Ale przeciez
wiadomo, ze ID w gramatyce odpowiada typowi string wiec to nie jest
problem napisac po prostu
<[ class $(classname) { def static 'a $(name) $(params) : $(type) } >]
ale wtedy params ma jakiegos typu E_fun_parms i jak chesz go rekurencyjnie
rozlozyc to mozesz napisac f params gdzie
f = function 
E_fun_parm ( s, t ) -> ...
E_fun_parm ( s, t ) :: xs -> ...
albo pozwolic na pisanie rzeczy typu E_fun_params w krzakach i wtedy
f = function 
<[ [ $(s) : $(t) ] ]> -> ...
<[ [ $(s) : $(t), $(xs) ] ]> -> ...
 
> Nastêpnym razem przejrzê ca³± sk³adnie jêzyka i spróbujê okre¶liæ jak±¶ spójn± 
> sk³adnie do jej rozbioru. Napiszcie jednak co my¶licie dok³adnie o $ i jak 
> g³êboko on powinien siê wg³abiaæ.

Mysle, ze dosc gleboko. Mysle tez, ze na wstepie dobrze by bylo to zrobic
wlasnie w jakis prosty sposob hackujac kompilator, np. wlasnie
rozszerzajac gramatyke i robiac jedna funkcje zamieniajaca na zwykle
parsetree. Potem moze sie okaze ze potrzeba cos wiecej albo inaczej, ale
przynajmniej bedzie widac co :).

- lk




More information about the devel-pl mailing list