fkolenak / FJPCompiller

0 stars 0 forks source link

Aktualni stav prekladace #1

Closed jstrolen closed 8 years ago

jstrolen commented 8 years ago

@Yggdrasil88 @johnny-wolf Takze zase ja Prectete si http://kifri.fri.uniza.sk/~bene/vyuka/kompilatory/prednasky-prezentace/Predn-01-text.pdf Je to sice z nejaky Zilinsky univerzity, ale jsou tam pekne popsany zakladni soucasti analyzatoru, vychazel jsem z toho.

  1. Scanner - lexikalni analyzator: Projde text a vytvori z nej tokeny. Token obsahuje ID tokenu(jeho druh) a lexem (puvodni text zadany uzivatelem), v tom dokumentu je to vysvetleny. Vstupem je tedy String (text programu), vystupem List. Tohle by uz melo fungovat.
  2. Parser - Syntakticky analyzator: Prochazi tokeny a podle gramatiky tvory syntakticky strom. Mirne jsem poupravil gramatiku (program nekonci teckou, ale vsechny bloky konci strednikem; podminene prirazeni zacina "?"; prirazeni ma pred cislem rovnitko navic - napr a = b = c = = 5; ...; viz gramatika nize), ke vsem zmenam jsem mel duvod (mame tu gramatiku slozitejsi nez je klasicka pl/0). I tohle by uz melo z vetsiny fungovat, zitra(dneska) to jeste poradne otestuju. To muzete zkusit i vy. Stahnete si odtud: https://code.google.com/p/structure-graphic/downloads/list jarko a pridejte si ho do projektu jako externi jar knihovnu. Umi to pekne ten vygenerovany strom vykreslit.

Pokud tu knihovnu mate, muzete to primo z mainu spoustet, text programu je v promenne "text". Do konzole to vypise tokeny(lexem a id tokenu - vystup scanneru) a zobrazi okynko se stromem (vystup parseru). Pokud se zada chybny program, budto bude hlasit chybu nebo se zacykli (na to jeste kouknu). Ted uz tedy chybi jen ten strom projit a tvorit z nej instrukce (mozna by bylo snazsi namisto tvorby instrukci rovnou spoustet kod?? == delat interpret, to asi taky muzem??).

BTW napiste jestli chcete ztopit ty OSka

Gramatika:

program -> blok

blok     -> [ "const" identifikátor "=" {identifikátor "="} ( číslo | "-" číslo ) {"," identifikátor "=" {identifikátor "="} ( číslo | "-" číslo ) } ";"]
            [ "var" identifikátor { "," identifikátor } ";"] 
            { "procedure" identifikátor "(" [identifikátor [{"," identifikátor}] ")" blok  } 
            [ příkaz ] 
            "return" [vyraz] ";" . 

příkaz   -> identifikátor "=" {identifikátor "="} vyraz ";" | 
            "call" identifikátor "(" [vyraz {"," vyraz}] ") ;" | 
            "begin" příkaz { příkaz } "end" | 
            "if" podmínka "then" příkaz | 
            "if" podmínka "then" příkaz "else" příkaz | 
            "while" podmínka "do" příkaz | 
            "do" příkaz "while" podmínka ";" | 
            "switch" výraz "case" ( číslo | "-" číslo ) ":" příkaz { ", case" ( číslo | "-" číslo ) ":" příkaz } . 

podmínka -> výraz ("==" | "<>" | "<" | ">" | "<=" | ">=" | "AND" | "OR") výraz | 
            "!(" podmínka ")" . 

výraz    -> term {("+" | "-" ) term } | 
            "?" podmínka "?" výraz ":" výraz . 

term     -> faktor { ("*" | "/" ) faktor } . 

faktor   -> identifikátor | číslo | "-" číslo | 
            "call" identifikátor "(" [vyraz {"," vyraz}] ")" | 
            "(" výraz ")" . 

Update 5. 1. 2016
jstrolen commented 8 years ago

@Yggdrasil88 @johnny-wolf Mame zase po pulnoci, takze co je hotovo: Scanner i Parser by uz meli fungovat (ridi se gramatikou v predeslem prispevku) a zaciname generovat kod, takze prochazime syntakticky strom a vytvarime kod. Uz by to melo umet alokovat misto pro promenne a konstanty, tzn. najdu na zacatku stromu vetev const -> vytvarim konstanty, najdu vetev variables -> vytvarim misto pro promenne atd. Struktura kodu a zasobniku je popsana v kodu (CodeGenerator.java). V podstate na zacatku zasobniku jsou tri mista o ktery se nestarame, pak misto pro navratovou hodnotu zavolane fce, pak jsou ulozeny konstanty, pak se vyhradi misto pro promenne a dale uz se bude neco pocitat. Ohledne kodu, postupujeme podle vetvy stromu, takze v podstate nejprve vytvorime misto v zasobniku tak, jak jsem popsal, preskakujeme kod procedur a prechazime na vykonny kod, z toho se pak budeme volanim call vracet zpet na preskocene procedury (pri zavolani fce), navratovou hodnotu ukladame na 4. misto (1. pouzitelne) zasobniku predesle metody (main nic nevraci) a nakonec pomoci RET se dostaneme zpet za misto volani. Zitra(dneska) uz asi zacnu delat generovani i pro ty vykonny prikazy.

fkolenak commented 8 years ago

Ok, ja si to pak projdu, pripadne zitra dotazy. Taky se budem muset domluvit co budeme delat my, jinak nam seberes vsechnu srandu ty :)

Zajimavy ze mi nechodi emaily, jsem si s tim ted trochu hral tak snad uz mi prijde kdyz nekdo neco napise.

jstrolen commented 8 years ago

@Yggdrasil88 @johnny-wolf Tak ja schvalne pridavam do prispevku @mentiony aby vam to chodilo a ono nic :)

Chtel jsem se zeptat na ten zitrek - je nezbytny abych se dostavil, nebo staci kdyz se uvidime v pondeli (je zase matika)? Nejak se mi tam nechce a pak PIA stejne odpadaji (ne ze bych na ne chodil), tak mi napadlo, ze jestli nemate neco hodne urgentniho, ze by jsme to mohli pro tentokrat odlozit.

Jinak co se tyce toho programku, mam to ted docela slusne rozjety, tak zkusim udelat co zvladnu, vam pak s radosti prenecham dokumentaci, komentovani kodu, atd. :)

fkolenak commented 8 years ago

@jstrolen Jasne to mi vubec nevadi... no zitra se schazet vubec nemusime me slo jen o rozdeleni prace.

PS: ted uz mi mail prisel, asi mu vadilo ze jsem tam mel seznamackej mail :)

jstrolen commented 8 years ago

@Yggdrasil88 @johnny-wolf
Den uz nam pomalu skoncil, takze co mame hotovo: Fungovat by melo prirazovani, pocitani (+ - * / závorky) a snad i volani fci (procedur). Naopak chybi dodelat if, switch, case, do, while, podminene prirazeni. To snad zvladnu zitra. K tomu jak to funguje:

Mejme vstup:

var a;
a= =1+2
return;

Program nam vygeneruje kod:

0 INT 0 4  //V zasobniku vytvorime tri mista pro hlavicku a 1 misto pro navratovou hodnotu volanych fci: 
1 INT 0 1  //Vytvorime misto pro promennou "a"
2 LIT 0 1  //Probiha prikaz prirazeni - na vrchol bufferu umistime konstantu 1
3 LIT 0 2  //Dalsi na rade je konstanta 2
4 OPR 0 2  //Provedeme operaci souctu - zmizi nam z bufferu 2 a 1 a objevi se 3
5 STO 0 4  //Ulozime vrchol bufferu na adrusu promenne a
6 RET 0 0  //Ukonceni programu

Dalsi priklad:

const a=5, b=10;
var c;
c= =a*(b+15);
return;
0 INT 0 4  //Hlavicka a misto pro navrat z volane fce
1 LIT 0 5  //Ukladame konstantu a do zasobniku
2 LIT 0 10  //Ukladame konstantu b do zasobniku
3 INT 0 1  //Vytvorime misto pro promennou c
4 LOD 0 4  //Ze zasobniku vytahneme promennou b
5 LOD 0 5  //Vytahneme promennou c
6 LIT 0 15  //Pridame konstantu 15
7 OPR 0 2  //Provedeme soucet c + 15 => 25
8 OPR 0 4  //Provedeme nasobeni 5 * 25 => 125
9 STO 0 6  //Ulozime na misto promenne c
10 RET 0 0  //Konec programu

A neco tezsiho:

const a=b=1, c=2;
var d, e;
procedure proc1(a, b) 
 return a * b;
procedure proc2(a) 
 var b; 
 b= =a*2 
 return call proc1(a, b);
begin
 d= =call proc1(a, c) - call proc2(b);
 e= =c;
end
return;
0 INT 0 4  //Hlavicka a misto pro navr. hodnotu (tentokrat ji pouzijeme)
1 LIT 0 1  //1 do zasobniku - konstanty a, b
2 LIT 0 2  //2 do zasobniku - konstanta c
3 INT 0 2  //misto pro promenne d, e
4 INT 0 2  //Koukneme na procedury na teto urovni (proc1, proc2) => nejvice argumentu ma proc1 - 2 argumenty => vyhradime dve mista
5 JMP 0 34  //Dale nasleduji definice procedur, vykonny kod mainu je za nimi - preskocime na adresu 34

 6 INT 0 4  //Zacatek proc1 - vytvarime hlavicku a misto pro navr. hodnotu
 7 INT 0 2  //proc1 ma dva argumenty - vytvorime pro ne misto
 8 LOD 1 8  //A hned si nastavime hodnotu prvniho argumentu na spravnou hodnotu = sahname o uroven vyse (proto je za LOD cislo 1) na misto kde je ulozen prvni argument fce. a dame ho na vrch bufferu
 9 STO 0 4  //A vrch bufferu dame na misto kde ma fce definovan prvni argument (misto pro nej jsme definovali v kroku 7)
 10 LOD 1 9  //To same co krok 8, pouze sahneme na druhou pozici - ziskame hodnotu konstanty c, v ramci teto metody ma nazev b, ulozime na vrch bufferu
 11 STO 0 5  //A opet jako v kroku 9 ukladame na misto pro argument (misto kde je promenna b)
 12 LOD 0 4  //A jsme v returnu, musime vynasobit a s b => dame si na vrch bufferu hodnotu a
 13 LOD 0 5  //A hodnotu b
 14 OPR 0 4  //A provedeme operaci nasobeni - z bufferu nam zmizi dve posledni hodnoty a objevi se jejich nasobek
 15 STO 1 3  //A provedeme return = ulozeni vrsku bufferu do mista k tomu urcenemu v nadrazene metode. Nadrazena metoda je main, ukladame tedy hned za hlavicku (vzpominate na prvni prikaz?)
 16 RET 0 0  //Navrat z fce za misto, kde jsme ji zavolali

 17 INT 0 4  //Jsme v metode proc2, opet hlavicka
 18 INT 0 1  //proc2 ma jeden argument, vyhradime si na nej misto
 19 LOD 1 8  //Sahneme o uroven vyse pro argument, dame si ho do bufferu
 20 STO 0 4  //Ulozime buffer do mista promenne a
 21 INT 0 1  //proc2 ma jednu promennou, vytvorime pro ni misto
 22 LOD 0 4  //Provadime prirazeni do b -> potrebujeme hodnotu a -> sahneme si pro ni a dame do bufferu
 23 LIT 0 2  //Prdame 2
 24 OPR 0 4  //A provedeme vynasobeni
 25 STO 0 5  //Vrsek bufferu ulozime do promenne b
 26 LOD 0 4  //Jsme v returnu - musime zavolat proc1 a to znamena pripravit pro nej argumenty -> na vrch bufferu dame nase lokalni a (ne konstantu a)
 27 STO 1 8  //A protoze proc1 ma za nadrazenou metou main, ukladame argumenty do main -> ulozime vrsek zasobniku o uroven vyse (tzn do main, proto je za STO jednicka) na prvni misto pro argumenty
 28 LOD 0 5  //Dale potrebujeme predat b - opet nase lokalni b, ne konstantu z mainu - sahneme pro nej a dame do bufferu
 29 STO 1 9  //A jako v radce 27 ukladame do nadrazeneho mainu, tentokrat na druhe misto
 30 CAL 1 6  //Promenne jsou na svych mistech, volame proc1 z metody proc2
 31 LOD 1 3  //Jsme zpatky, protoze ma proc1 nadrazenou metodu main, bude jeji navratova hodnota tam -> sahame o uroven vyse do mista pro navratovou hodnotu
 32 STO 1 3  //A ted samotny return - vracime ziskanou hodnotu, ktera je ted na vrsku bufferu, nase nadrazena metoda je main -> ulozime navratovou hodnotu tam (tedy do stejneho mista, odkud jsme v predesle instrukci cetli)
 33 RET 0 0  //A navrat za misto valani proc2

34 LOD 0 4  //Konec procedur, metody mainu, budeme volat proc1 -> potrebujeme a -> dame si ho na vrsek bufferu
35 STO 0 8  //Ulozime vrsek bufferu (konstanta a) do mista pro argumenty fce
36 LOD 0 5  //Stejne tak potrebujeme konstantu c, dame na vrsek bufferu
37 STO 0 9  //A ukladame vrsek bufferu na druhou pozici mista pro argumenty fci
38 CAL 0 6  //Argumenty jsou pripraveny, volame proc1 -> skok na pozici 6
39 LOD 0 3  //Jsme zpet z fce, ulozime si navracenou hodnotu na vrchol zasobniku
40 LOD 0 4  //Jdeme na volani proc2 -> potrebujeme b -> ulozime ho na vrsek bufferu
41 STO 0 8  //A vrsek bufferu ukladame na pozici pro argumenty - tentokrat vyuzijeme jen prvni pozici
42 CAL 0 17  //A muzeme volat metodu proc2 - skok na 17
43 LOD 0 3  //A jsme doma z proc2 -> vytahneme si jeji navratovou hodnotu na zasobnik
44 OPR 0 3  //V zasobniku je navratova hodnota volane proc1 i proc2 -> muzeme proves odecteni
45 STO 0 6  //A vysledek ukladame do promenne d
46 LOD 0 5  //Jeste musime priradit do e -> do bufferu dame konstantu c
47 STO 0 7  //A vrsek bufferu dame do e
48 RET 0 0  //Vse je hotovo, koncime

Pozor u procedur - kod generujeme tak, jak je zapsan => v predeslem pripade bych NEMOHL z proc1 volat proc2. Proc? Protoze proc2 v dobe tvorby proc1 jeste neexistuje. Je to podobne asi jako u C++, tam by jsme v tomhle pripade nejprve museli vytvorit prototyp. V nasem programu to ale resit nebudeme a proste stanovime, ze procedury muzeme volat az pote, co jsou vytvoreny.

Zkuste si tyhle priklady spustit v debuggeru(mozna mu budou vadit komentare) http://www.kiv.zcu.cz/~lobaz/fjp/debug_PL0/index.php a kouknete co dela stack.

PS. psal jsem to hodinu, tak si to prectete.

jstrolen commented 8 years ago

@Yggdrasil88 @johnny-wolf Takze mame zase druhou vecerni. Udelal jsem jednoduche GUI, provedl mensi zasah do gramatiky (vsechny prikazy (vcetne begin end) musi koncit strednikem (kosmeticka uprava)), dodelal podminky (if, switch a spol.) a celkove prosel kod, smazal par nepotrebnych veci, neco upravil a hlavne pridal komenty do tridy generujici kod, tak uz se v tom mozna i vyznate. Celkove vzato je program "hotovy", s tim ze tam samozrejme muzou byt bugy. Ve volnych chvilych to zkusim projit. To je apel i na vas, aby jste si to stahli, zkusili jestli to funguje spravne (knihovna pro generovani stromu - viz vyse - uz neni potreba). Pokud neco nebude fungovat, dejte vedet. Hlavne ted jde o tom zkontrolovat, jestli nam funguji vsechny mozne kombinace prikazu, tedy jestli spravne resime vsechny vetve vytvoreneho stromu a na neco jsme nezapomneli.

jstrolen commented 8 years ago

@Yggdrasil88 @johnny-wolf
Tentokrat jen v rychlosti:

  1. Vsechny prikazy krom endu konci strednikem
  2. Melo by to spravne generovat prikazy pro vsechny programy z portalu (je treba upravit jejich syntaxy, ale funguji)

Potrebujeme tedy otestovat i vsechny nami dodelane konstrukce a mozna dodelat optimalizaci kodu - to by znamenalo predevsim sloucit vsechny prikazy int, ktere jdou za sebou (je treba dat pozor, ze pokud sloucime dva prikazy, musime pak opravit prikazy, ktere se odkazuji na adresu - call a skoky).

fkolenak commented 8 years ago

@jstrolen @johnny-wolf Ty testy by sme mohli delat my.:)

jstrolen commented 8 years ago

@Yggdrasil88 @johnny-wolf
Takze po delsi dobe zase ja. Dnes jsem opravil par dalsich veci (kontrola poctu argumentu u volane fce, switch vyhodnocuje podminku jen jednou, slouceny prikazy int, oprava chybovych vypisu). Timto to v podstate prenechavam vam na dodelani. Takze, co je potreba udelat: 1) Testovani: Vse dukladne projit a odkrokovat v debuggeru. Musi se predevsim otestovat, jestli nam funguji vsechny vetve generovaneho stromu - v podstate to znamena vzit si k ruce gramatiku (aktualni gramatika je vyse) a vyzkouset vsechny moznosti. Pokud neco nepujde, muzete to zkusit opravit, nebo mi dejte vedet a ja na to kouknu. Take je potreba otestovat, jestli funguje v podmince AND a OR - ty v puvodni PL/0 nejsou, takze jsem je vytvarel rucne. Spravna funkce je takova, ze 0==false, cokoli jineho je true. 2) Refaktoring kodu - vsechno to projit, prepsat vse do jednoho jazyka (vyberte si, jestli to cele chcete mit cesky nebo anglicky, komenty asi nevadi). 3) Projit to a zjisti, jestli neni potreba neco dodefinovat - napr. v pondeli nam rikal, ze mame dodefinovat, jak se bude program chovat, kdyz zadame fci. jiny pocet argumentu, nez na ktery je stavena (to jsem dodelal dnes - kompilator nam nedovoli zadat jiny pocet). 4) Dodelat dokumentacni komentare do kodu, pokud si nebudete s necim jisti, dejte vedet. 5) Dokumentace - az neco budete mit, dejte to sem, chtel bych se na to kouknout.

Tak si to mezi sebou nejak rozdelte a zacnete neco delat.

Take pripominam, ze 7.12. to budeme spolecne prezentovat, tak se na to pripravte (nevim jak to bude probihat, mozna pripravit nejakou prezentaci???).

fkolenak commented 8 years ago

@jstrolen Tak tenhle tyden se podivam na to testovani, zatim jsem se dival na konstrukci if else a podminky ktery muzou mit (AND a OR jeste ne). Zatim funkcnost ok, jen nekde se mezery ignoruji nekde ne.

jstrolen commented 8 years ago

@Yggdrasil88 OK. S tema mezerama ted nevim jak to myslis. Vstup programu se nejdrive prevadi do tokenu, takze i kdyz napisu treba "(a+b)" prevede se mi to do 5 tokenu - LBRAC, IDENT, PLUS, IDENT, RBRAC. Melo by to fungovat tak, ze klicova slova mohou byt oddelena mezerou vzdy + nektera toto oddeleni nevyzaduji. Kdyz kouknes do tridy Scanner, tak v poli KEYWORDS jsou klicova slova, ktera se mohou oddelovat mezerou (vsechny) a v KEYWORDS_MIDDLE jsou navic ty, ktera se oddelovat nemusi (zavorky, znamenka, ...). Kdyztak napis priklad kdy to funguje divne a ja na to kouknu.

Taky by se to melo ridit gramatikou, takze kdyz neco nebude chtit fungovat, kouknete vyse na gramatiku - napr. vsechny prikazy konci strednikem s vyjimkou begin - end. If nebo else tam sice strednik napsany nemaji, ale konci prikazem - a prikaz konci strednikem, takze se tam jeden strednik stejne dostane. Podobne dejte pozor na switch - kazdy case ma jeden prikaz, takze pokud tam date begin - end, strednikem to koncit nebude a pred dalsim case bude oddelen carkou. Pokud tam date ale treba prirazeni, tak to strednikem konci, takze tam budete mit strednik a hned za nim carku. A jeste pripominam, ze u podmineneho prirazeni mame na zacatku otaznik navic - "? a>b ? 5 : 1". A u prirazeni do promenne (ne do konstanty) musi byt na konci rovnitko navic (musi byt s mezerou, jinak by to bylo porovnani) - "a = b = c = d = = 1;".

fkolenak commented 8 years ago

@jstrolen Cau, promin tak jsem se k tomu jeste nedostal, dnes jsem chtel alespon neco udelat, ale jeste porad jsem se ucil na TGD. Dam si deadline, ze do stredy to budu mit odzkouseny. Takze snad se na necem nezaseknu :] Vzdy si napisu jakym kodem jsem testoval dany prikaz, to tu pak postnu abys na to mohl kouknout pripadne napsat na co jsem zapomel :]

jstrolen commented 8 years ago

@Yggdrasil88 @johnny-wolf
K tomu testovani, jde tam o to, ze jak mame tu gramatiku, musime vyzkouset vsechny moznosti, takze treba: prikaz ma 8 moznosti na co se muze prepsat - tak je vsechny vyzkousim; podminka ma dve - vyzkousim je. Navic pokud se nekde neco muze objevit vicekrat (napr. term se mi prepise na faktor a za nim mohou -ale nemuseji- nasledovat dalsi faktory oddelene znamenky * nebo /), tam by to take chtelo otestovat vice moznosti (napr. zadam jen jeden term, pak zadam dva, pak tri a kouknu, jestli to ve vsech moznostech funguje). Taky vyzkouset vsechny moznosti u podminek (if, while, do, switch) - vyzkouset jestli spravne funguji vsechny vetve. Pak taky otestovat volani fci. - napr. jestli spravne funguje, pokud budu volat funkce definovane o par urovni vyse (treba v mainu mam definovany fce1() a fce2(), pak z vnitrku fce2() volam fci1() - ta je definovana o uroven vyse) - vyzkouset jestli funguje navratova hodnota a jestli v nich muze menit promenne definovane o par urovni vyse. Taky se podivat, jestli mi to nedovoli menit hodnotu konstanty (i kdyz to bych mel mit snad osetreny). To je vse, co mi v tuhle chvili napada. Vzdycky si napis kod, a pouzij ten debugger, co jsem tu zminoval a krokuj. Co ktera instrukce dela neni zase tak tezky pochopit. Koukni na tech par prikladu vyse, tam jsem si dal praci to vsechno komentovat. Od doby co jsem to psal se toho moc nezmenilo (maximalne se sloucili INTy).

Ted jeste k tomu zitrku. Predpokladam, ze si to oba projdete (je mi jasny, ze jste se na to zatim nekoukli), a udelate prezentaci. No a pak nekdo (Honzo), si pripravi povidani, ktery tam prednese (snad to dopadne lepe nez ty OS :)). Ja obstaram pripadny dotazy.

Jak tak koukam na ty body co tam mame mit, tak: 1) Zdrojovy a cilovy jazyk - takze mozna ukazat gramatiku (ta co je v prvnim prispevku je aktualni) a pripravit si nejakej peknej kousek kodu, ktery jde prelozit (neco, kde se trochu blejsknem) 2)Obecna struktura - Pouzivame rekurzivni sestup, znovu opkuju, ze: Nejprve probiha lexikalni analyza - Scanner (vstup String, vystupem ArrayList Tokenu, kde kazdy token obsahuje id (to urcuje jestli jde o promennou, cislo, klic. slovo if, klic. slovo dvojtecka, atd.) a lexem (to je jen String ze vstupu, ktery odpovida aktualnimu tokenu - pouzivame to pouze kvuli identifikatorum (aby jsme vedeli, jak uzivatel oznacil promenne, konstanty a fce.) a cislum)). Pak tohle pole vezmeme a prevadime ho na syntakticky strom - Parser (prochazime iterativne tokeny a rekurzivnim sestupem zpracovavame - kouknete do te tridy Parser, postupne z nich budujeme strom - Koren ma token null, vsechny ostatni uzly odpovidaji tokenum (vlastne jenom umistujeme ty tokeny z toho pole do stromu). To jak ty uzly vypadaji mate taky napsano v komentech toho parseru). A posledni krok - samotne generovani kodu (vstupem je strom, ten postupne prochazime a generujeme kod - funguje to vlastne shodne jako Parser (jedna se zase o nejaky rekurzivni sestup), s tim, ze zatimco minule jsme generovali strom, nyni ukladame do pole prislusne prikazy, vystupem je tedy pole prikazu String). Pokud se v kterekoli casti objevi neco, co tam byt nema (odporuje to nasi definici jazyka), vyvola se vyjimka. To mi pripomina, ze mi mame nas jazyk definovany gramatikou a navic mame stanoveno, ze fce musi prijimat stejny pocet argumentu, pro jaky byla definovana(to v gramatice stanoveno neni), nic dalsiho mi nenapada. 3) Tabulka symbolu - v nasem pripade je to strom, pro kazdou fci je jedna uroven (tzn. nejvyse je main, ten obsahuje pole konstant a promennych (udaj, kde se nachazi v zasobniku) a potomky - temi jsou fce definovane na dane urovni - tzn. jmeno fce a pak zase nejaky seznamy a potomci jsou dalsi fce.). Z toho vychazi i viditelnost promennych a fci - videtelne jsou ty, co jsou na nasi urovni nebo na urovnich vyse. Datovy typ mame jen int, v pripade podminky je nula false. Pridelovani pameti - tohle jsem uz zminoval nekolikrat - na zacatku kazde fce (i mainu) vyhradime v zasobniku misto pro: hlavicku, navr. hodnotu, argumety fce, konstanty, promenne, argumenty na dane urovni definovanych fci. Parametry muzeme predavat pouze hodnotou - na prislusne misto v zasobniku ulozime hodnoty a zavolame fci, ta si na tohle misto sahne a nacte si argumenty na sve misto v zasobniku. Navratova hodnota funguje obdobne - na konci fce. ulozime navr hodnotu (defaultne nula) na prislusne misto nadrazene fce (rodici - te fci, kde je ta volana fce definovana) a pokud navr. hodnotu potrebujeme, tak si na tohle misto pro ni sahneme. 4) Delali jsme v Jave, pouzivali jsme knihovnu StructureGraphic pro vizualizaci syntaktickyho stromu a tabulky symbolu. Mame to na githubu (ale at sem radsi nekouka :)). No a pak reknete jak poctive jste testovali :)

Ja se dneska (uz je nedele) ucim TGD, takze prezentaci pripravite a naucite se povidat vy. Ja pak, jak jsem uz zminil, obslouzim pripadny dotazy, atd.

Pokud neco nebude jasny, dejte vedet. Jo, a tu prezentaci bych rad videl, tak az to budete mit hotovy kdyztak to sem dejte, at na ni taky kouknu.

fkolenak commented 8 years ago

@jstrolen https://www.dropbox.com/s/ux6fuudlix853e4/prezentace.pdf?dl=0 Aktualni verze, jeste neprosla revizi od Honzy :]

Update: Takze Honza tohle schvalil, co ty na to Pepo?

jstrolen commented 8 years ago

@Yggdrasil88 @johnny-wolf
Bezva. Jen jsem si ted uvedomil, ze mame mensi nedokonalost v gramatice - číslo u nás značí pouze kladná čísla, tzn. nemůže začínat minusem. Když kouknete v gramatice na faktor, tak tam je ... | číslo | "-" číslo | ... Takže to, co se přepisuje přes faktor (přiřazení do proměnné) funguje správně a můžu zadat i negativní hodnotu. Ale u přiřazení do konstanty a u switche máme natvrdo číslo (tzn. pouze kladná čísla). Zkusím na to teď kouknout, v podstatě tam namísto číslo bude (číslo | "-" číslo). Jedná se jen o malou úpravu při generování syntaktického stromu, pak už půjde zadávat i záporná čísla. A jen taková malinká poznámka - koukal jsem, že tam je screen ze starší verze programu, ale krom sloučení těch INTů tam není rozdíl.

jstrolen commented 8 years ago

OK, je to tam, teď by měly jít používat záporná čísla všude. Gramatika výše je opravena.

fkolenak commented 8 years ago

@jstrolen Jo ja si to stahoval pred nedavnem, ted jsem zapomel updatnout. To ze nemuzou konstanty byt zaporne neni problem, vzdyt mi jsme tvurci :D

Mam ten screen udelat znovu?

jstrolen commented 8 years ago

Jak chces, necham to na tobe. Mel byl jeden navrh, jestli se ti do toho chce, mozna by bylo dobry upravit screen z programu a dat tam neco takovyho:

var x;
procedure addOne(p)
  return p + 1;
begin
  x= =1;
  x= =call addOne(x);
  if x==2 then x= =-1;
end
return;

Je tu videt ten return. Mimochodem, ty ostatni veci o kterych se zminoval (jak to funguje, tabulka symbolu, ...) to uz potom budeme (Honza bude) jen rikat? Myslim, to v prezentaci nebude?

fkolenak commented 8 years ago

@jstrolen Co ted? Tim myslim, ze je to upraveny, koukni znovu.

jstrolen commented 8 years ago

@Yggdrasil88 @johnny-wolf
Bezva, asi to takhle muzeme nechat. Uz se vyjadril Honza?

jstrolen commented 8 years ago

@johnny-wolf
OT, ale chci se zeptat, jestli dneska na přednášce z SU říkal něco o zápočtu/zkoušce (třeba mezní termín odevzdání semestrálky). Dík

fkolenak commented 8 years ago

@jstrolen Cau, tak zatim jsem nic spatne nenasel. Veskery zaklad je pokryty. Jediny co mi zbyva jsou ternarni operatory. A jeste zkusim jestli funguje return u funkce spravne a zanoreni prikazu. Vic mi zatim nenapada. Zkousel jsem i par veci, jestli jsou osetreny a byly, takze parada. :)

fkolenak commented 8 years ago

@jstrolen Zkouseni hotovo, nenasel jsem nic spatne, je mozny ze jsem neco z tech slozitejsich veci zapomel, ale normalni pripady jsou vsechny pokryty. Komenty kodu jsou hotovy az na tu jednu tridu, prosim projdi si to jestli to vsude dava smysl. Jeste nam rikali, ze budou chtit vstup z konzole, potom vystup bude pravdepodobne do souboru. Jeste jsem si vzpomel, nechteli mit i vypsanou tabulku symbolu?

@johnny-wolf Prosim zacni delat na dokumentaci. Titulni stranu, uvod, gramatiku bys mel zvladnout sam, zbytek by mel byt napsany tady. Vic infa co je tam potreba je na courseware. Je jedno v cem to bude delany :]

Mezní termín odevzdání je pevně stanoven na 8. 1. 2015

Jeste jedna vec, posilali ste ten email s tou prezentaci?

jstrolen commented 8 years ago

@Yggdrasil88 @johnny-wolf
Zdravim, omlouvam se za zpozdeni.

Prosel jsem kod a: Cely kod (vyjma prog. komentu) by mel byt nyni anglicky Dodelal jsem komenty do Parseru Mensi zmena v gramatice (zase) - odpada nutnost pouzivat dve rovnitka na konci prirazovani do promenne - uz by to tedy melo fungovat jako u normalnich jazyku. Dva otazniky u ternarniho operatoru zustavaji. Vlastni preklad se nyni spousti ze pridy PL0_Compiler Pridan preklad do souboru - syntaxe je "PL0_Compiler.jar ", tzn musi se zadat dva parametry - vstup a vystup, v opacnem pripade se spusti GUI. Zmena u vytvareni promennych - dosud jsme pouze alokovali misto na zasobniku - hodnota neicializovane promenne tedy nebyla urcena. Nyni je kazda promenna automaticky inicializovana na nulu. Takze v kodu se napr. "INT 6" meni na "INT 4 LIT 0 LIT 0". I tohle je soucasti definice naseho jazyka, takze by se o tom mela objevit zminka v dokumentaci.

S tou tabulkou symbolu nevim. Pokud ji chcete, tak dejte vedet jaky to ma mit format a ja ten nas strom muzu vypsat. Jedina potencialni potiz ktera mi napada jsou chybove hlasky, ktere nejsou prilis prehledne, ale moc se mi v tom nechce stourat.

Jinak by to asi melo byt vse. Pokud bude potreba jeste neco, dejte vedet, uz bych mel zase odpovidat pruzneji :).

PS: Ja prezentaci neposilal. A az budete mit dokumentaci tak to sem hodte nebo mi ji poslete, at na to muzu taky mrknout.

fkolenak commented 8 years ago

@jstrolen Moje zmeny se ti nelibili jo? A moc se mi nelibi to melo fungovat... funguje to teda? :smile:

Jeste jedna vec pouzivej zavorky u if else... ted uz to nech, ale je to mnohem prehlednejsi, kdyz se to pak cte.

Komentare si cetl dava to smysl?

jstrolen commented 8 years ago

@Yggdrasil88
Zmeny byly v pohode, jen jsem mel cast tech oprav (dokumentace kodu, nova trida pro preklad) uz par dni hotovy a vcera jsem dodelaval to kodovani. No a kdyz jsem to pak chtel pushnout zjistil jsem, zes mi predbehl. A protoze si moc nerozumim se synchronizaci workspace, nakonec jsem nahodil vsechny moje zmeny. Jediny co jsem ti prepsal je ten zpusob vstupu ze souboru. Nevim jak to chce, tys to zobrazoval do GUI, ja to rovnou ukladam. Klidne si tam vrat zpatky to svoje. Tyhle veci jsi zminil pod mym jmenem, tak jsem to bral jako svuj ukol.

Co se tyce toho melo by fungovat, zkousel jsem to na nekolika pripadech a funguje. Puvodne to fungovalo tak, ze se vzdy nacetla promenna a rovnitko, a pokud nebyl dalsi vstup rovnitko, sekvence se zopakovala. V opacnem pripade se jednalo o ono rovnitko navic, po kterem nasledovala hodnota. Nyni se opet nacte promenna s rovnitkem, ale pak se to kontroluje ob jeden token. Pokud je na tomhle miste rovnitko, sekvence se zopakuje. Pokud tam rovnitko neni, nacitame hodnotu. Podle gramatiky neexistuje zadna jina moznost, kdy by se nam na tehle pozici rovnitko mohlo objevilo.

Komentare jsem samozrejme procetl. Jsou sice strucnejsi (ja uz ty svy pak psal taky tak), ale smysl urcite davaj. Melo by to byt v pohode.

S tema zavorkama, zvykl jsem si u kratsich prikazu ten prikaz psat hned na jednu radku za if/else. Ale je pravda, ze i ty kratsi prikazy mi nekdy vyjdou dost dlouhy :)

fkolenak commented 8 years ago

@jstrolen Ja to tam delal jen aby se nereklo ze nemame vstup z konzole. To si uz udelal, takze neni duvod to tam znovu dodavat.

Ta sznchroniyace o kterych mluvis jsou konflikty. Ty nastanou kdyz dva delaji na stejnem souboru na stejnzch radkach, pak se musi vzbrat jakou cast kodu si nechat - vyresit konflikt.

If/else... co jsem byl u SocialBakers tak tam nam rikali ze tam ty zavorky chteji, jinak jsme byli trestany :smile: (svacina sefovi).

Komentare pisu strucne, koho zajima jak se to dela, at si precte kod. :smiley:

@johnny-wolf Uz dela na dokumentaci, jeste jsem nevidel uplne nejnovejsi verzi se zmenama co si tu napsal.

johnny-wolf commented 8 years ago

@jstrolen @Yggdrasil88 Hele hoďte mi sem někdo novou gramatiku, ať to můžu překlepat. Jinak dneska ti Fando snad pošlu tu dokumentaci (třeba i bez nově udělaný gramatiky) ale pošlu jí

johnny-wolf commented 8 years ago

@jstrolen @Yggdrasil88 takže dokumentace by měla být hotová a aktualizovaná s tim, že tam neni ještě upravená aktuální gramatika a závěr, ten byste měli vymyslet spíš vy dva.

fkolenak commented 8 years ago

@jstrolen Prozatimni verze: https://www.dropbox.com/s/p61a4r48fn7ii9w/FJP-dokumentace.pdf?dl=0 Ja tam hodlam zmenit jen par veci: hned za vyctem gramatiky je co se zmenilo to dam uz k zadani a reknu ze jsme standartni zadani rozsili o...

Nevim jestli stoji za to aktualizovat ten obrazek s gui {stara gramatika}

jstrolen commented 8 years ago

@Yggdrasil88 @johnny-wolf
Tak na to koukam a vypada to celkem slusne. Takze za me asi takhle:

1: Aktualni gramatika je v mym prvnim prispevku, celou dobu ji tam udrzuju aktualni. 
2: Ten obrazek bych asi zmenil, neni to nic zasadniho, ale bude lepsi tam mit ten novejsi.
3: K tomu vyctu co jsme implementovali jeste dopiste switch
4: U trid jeste pridat novou tridu PL0_Compiler. A mozna by nebylo od veci to tady jeste rozdelit na dve casti podle balicku, at mame oddeleny core od GUI.
5: U odstavce od přidělování paměti bych dal, že proměnné se s hodnotou nula už vytvářejí a neinicializují se až potom. 

Možná by bylo fajn tam i napsat, že náš jazyk je definován gramatikou + že máme pár dalších pravidel. Konkrétně - volané fci se předává takový počet argumentů, pro jaký byla vytvořena. Dále, podmínky vyhodnocujeme jako v C, 0 je false, ostatní hodnoty true. A nakonec ještě jednou zopakavat, že neicializované proměnné jsou defaultně nula. Tohle jsou věci na který se nás při těch prezentacích a když jsme mu to ještě předtím ukazovali ptal.

Zavěr nevim, něco si tam vymyslete. Ještě mi napadlo jestli nechce u toho vygenerovanýho kódu nějaký komentář, ale ono je to celkem logický, tak asi nebude potřeba.

PS: Odevzdává to jen jeden, nebo musime vsichni?

johnny-wolf commented 8 years ago

myslim že tim, že jsme tam podepsaný všichni tak jde jen o to, kdo tam dá svuj email, koho bude otravovat potom

fkolenak commented 8 years ago

No dal bych tam vsechny at nam vsem posle kopie :smile:

fkolenak commented 8 years ago

@jstrolen Do něj umístíte zdrojový text, skript k jeho překladu (.bat soubor, ant nebo jiný. Udelas to?

Ja mezitim vymyslim zaver (nejaky rady by se hodily) a hodim to sem na kontrolu.

fkolenak commented 8 years ago
jstrolen commented 8 years ago

@Yggdrasil88 Sry za delay, ant je hotov. Zavolani "ant" provede preklad programu (vytvori adresar bin a vytvori spustitelny jarko), "ant dokumentace" vytvori adresar doc s javadocem. Mrknu jeste na ty priklady.

U ty dokumentace: pekny, jen ta gramatika je lehce rozhazena, nejde s tim neco udelat?

fkolenak commented 8 years ago

@jstrolen to by mel udelat @johnny-wolf ja na to nemam IDE :D Myslim ze zmensenim pisma by se to mohlo vyrovnat.

jstrolen commented 8 years ago

@Yggdrasil88 @johnny-wolf
OK, tak priklady jsou hotovy, snad mu to takhle staci. Jeste koukam, ze v nove verzi dokumentace chybi zminka o prekladu z konzole. Jestli to tam date, dejte tam ten lepsi tvar "java -jar PL0_compiler.jar ", u toho bez java -jar neni nastave vystup u syso, takze to nevypisuje chyby. Odevzdává tedy jenom jeden?

fkolenak commented 8 years ago

@jstrolen Asi radeji vsichni, nikde nemaji napsano ze jen jeden ma odevzdat, odevzdavaci formular tam mame vsichni takze...

johnny-wolf commented 8 years ago

hlavně ještě dneska by to chtělo :P

jstrolen commented 8 years ago

@Yggdrasil88
OK, bude to jistejsi. Hodte sem pak celej ten zip se vsim vsudy, at odevzdavame vsichni totez.

fkolenak commented 8 years ago

@jstrolen Priste commit bez toho jar, ten si kazdy muze udelat sam a zbytecne zabira misto :]

johnny-wolf commented 8 years ago

nejde zobrazit

fkolenak commented 8 years ago

Preview failed. toho odt... pdf umi

johnny-wolf commented 8 years ago

pdf jsem projel, zdá se to v pořádku, pokud tam neni něco v logice, na to jsem už moc unavenej vyhledávat

jstrolen commented 8 years ago

Email tam jeste dodas, nebo dame kazdy svuj? A porad se mi moc nezda formatovani gramatiky, alespon to na par mistech trochu odsadit a zarovnat pod sebe.

fkolenak commented 8 years ago

myslel jsem ze formatovani udela Honza, ja enmam office jak jsem rikal...

johnny-wolf commented 8 years ago
fkolenak commented 8 years ago

Je tam spatne cislovani kapitol. a U prekladu a spousteni odsad ty body at jsou spravne. A zapomel jsem prikazy dat do italic