Ծրագրի կոմպիլիացիայի փուլերը

Ինչպես է ծրագիրը վերածվում մեքենային հասկանալի հրամանների հաջորդականության

David Sargsyan
Picsart Academy
5 min readAug 23, 2020

--

Որակյալ ծրագիր գրելու համար շատ կարևոր է հասկանալ, թե բարձր մակարդակի լեզվով գրված ծրագիրը ինչպես է թարգմանվում տվյալ համակարգչի պրոցեսորին հասկանալի հրամանների հաջորդականություն, և ինպես է համակարգիչը կատարում այդ հրամանները։

Հաճախ ծրագրավորողները մասնագիտանում են ինչ որ ծրագրավորման լեզվով ծրագրավորելու մեջ, բայց թե ինչպես է իրենց գրած ծրագիրը աշխատում ամենացածր մակարդակներում՝ դժվար են պատկերացնում։

Այս հոդվածում կներկայացվի քայլերի հաջորդականությունը, որոնցով անցնում է բարձր մակարդակի լեզվով գրված ծրագիրը մեքենայական լեզվով գրված ծրագիր դառնալու համար։ Ավելի մանրամասն կարող եք դիտել այս դասընթացը, որը կազմակերպել ենք Code Republic-ի հետ համատեղ։

Կոմպիլիացիայի փուլերը

Կոմպիլիացիայի փուլերը հետևյալն են.

Լեքսիկական անալիզ (lexical analysis)

Լեքսիկական անալիզի ընթացքում ծրագիրը բաժանվում է token-ների, որն իրենից ներկայացնում է զույգ՝ lexeme-ի և class-ի։

Class-ի տիպեր են օրինակ identifier-ը, keyword-ը, number-ը, «հավասար»-ի նշանը և այլն: Lexeme-ն իրենից ներկայացնում է սիմվոլների հաջորդականություն, որ համապատասխանում է տվյալ ծրագրավորման լեզվի քերականությանը։ Օրինակ, “this_is_variable_name”-ը lexeme է, որին համապատասխան class-ը “identifier”-ն է, C++ ծրագրավորման լեզվում “float”-ը “keyword” տիպի lexeme է, “143”-ը “number” տիպի lexeme է և այլն: Դիտարկենք C++ լեզվով գրված կարճ ծրագրի կտոր.

int main()
{
// this is a comment
int x, y = 2;
x = 10;
return 0;
}

Այս ծրագիրը կբաժանվի հետևյալ lexeme-ների, որոնցից ամեն մեկը պատկանում է իրեն համապատասխան class-ին ու կազմում token:

'int'  'main'  '('  ')'  '{'  'int'  'x' ','  'y' '=' '2'  ';'
'x' '=' '10' ';' 'return' '0' ';' '}'

Սինտաքս անալիզ (syntax analysis)

Լեքսիկական անալիզից հետո գալիս է հաջորդ փուլը, որը կոչվում է սինտաքս անալիզ։ Անունից արդեն կարելի է կռահել, որ նրա գործառույթը գրված ծրագրի սինտաքսի ստուգումն է. արդյո՞ք այն բավարարում է տվյալ ծրագրավորման լեզվի քերականության օրենքներին թե ոչ։ Եթե այն բավարարում է, ապա կոմպիլյատորը անցնում է հաջորդ փուլին, հակառակ դեպքում՝ հայտնում ծրագրի մեջ քերականական սխալի մասին։ Որպեսզի կոմպիլյատորը հասկանա, թե արդյոք տվյալ ծրագիրը համապատասխանում է տվյալ ծրագրավորման լեզվի քերականական կանոններին, նախ պետք է սահմանված լինի այդ լեզվի քերականությունը։ Լեզվի քերականական կանոնների սահմանման ձևին ծանոթանալու համար դիտարկենք մի օրինակ։

1) S -> cAd
2) A -> bc|a

Վերևում սահմանված է ինչ որ լեզվի քերականություն, որն ունի երկու կանոն։ Կանոնների մեջ մեծատառով գրված սիմվոլները տվյալ լեզվի սիմվոլների բազմությունից չեն, դրանք մեզ օգնում են քերականությունը սահմանելու գործում։ Փոքրատառով գրված սիմվոլները ներկայացնում են տվյալ լեզվում առկա սիմվոլների բազմությունը։ Հիմա հասկանանք, թե ինչ է նշանակում առաջին կանոնը։ Առաջին կանոնը նշանակում է, որ սիմվոլների հաջորդականությունը (այսպիսին է նաև ցանկացած ծրագրավորման լեզվով գրված ծրագիր) նշված քերականությանը բավարարելու համար անհրաժեշտ է (բայց ոչ բավարար, քանի որ ունենք նաև երկրորդ կանոն), որպեսզի այն սկսվի c սիմվոլով և ավարտվի d սիմվոլով։ Երկրորդ կանոնը մեզ ասում է, որ այդ c և d սիմվոլների արանքում պետք է լինի կա՛մ bc, կա՛մ a:

If-elseif-else statement-ի քերականությունը

Մանրամասները կարող եք դիտել այստեղ.

Սեմանտիկ անալիզ (semantic analysis)

Սինտաքս անալիզի փուլն անցնելուց հետո կոմպիլյատորի համար պարզ է դառնում որ գրված ծրագիրը քերականորեն համապատասխանում է տվյալ ծրագրավորման լեզվին։ Սակայն լեզվում բացի քերականական կանոններից կան սեմանտիկային վերաբերվող կանոններ։ Օրինակ C++-ում եթե նույն scope-ի մեջ հայտարարենք երկու նույն անունով փոփոխականներ, ապա սինտաքսիսորեն այն ոչ մի սխալ չի ունենա, բայց սեմանտիկայի տեսանկյունից այն չի թուլատրվում լեզվում։ Սեմանտիկ անալիզի ընթացքում ի հայտ են գալիս տիպերի անհամապատասխանության սխալներ, չհայտարարված, բայց արդեն օգտագործվող փոփոխականի մասին սխալներ, վերը նշված նույն scope-ում երկու նույն անունով փոփոխականներ հայտարարության սխալներ և այլն:

Միջանկյալ կոդի գեներացիա

Սեմանտիկ անալիզը բարեհաջող ավարտելուց հետո կոմպիլյատորը անցնում է հաջորդ փուլին, որը կոչվում է միջանկյալ կոդի գեներացիա (Intermediate code generation): Այս փուլի ընթացքում մեր գրված ծրագիրը թարգմանվում է մեկ այլ լեզվի, օրը կոչվում է միջանկյալ կոդ, քանի որ ընկած է տվյալ լեզվով գրված ծրագրից դեպի մեքենայական լեզու թարգմանության արանքում։

Միջանկյալ լեզուն բավարարում է որոշակի կանոնների, ու դեպի այդ միջանկյալ լեզու թարգմանությունը օգնում է կոմպիլյատորին ավելի հեշտությամբ այն թարգմանել մեքենայական կոդի։ Հիմնական կանոնը որին բավարարում է այդ միջանկյալ լեզուն դա այն է, որ կամայական վերագրման գործողության աջ կողմում կա առավելագույնը մեկ հանրահաշվական օպերատոր։ Դիտարկենք մի օրինակ։

// in current language
d = (a+b)*c + a
// in intermediate language
t1 = a + b
t2 = t1 * c
t3 = t1 + t2

Վերը նշված օրինակ վրա տեսանք թե ինչպես է կոմպիլյատորը մեր լեզվով գրված ծրագիրը դարձնում միջանկյալ լեզվով գրված ծրագիր։ Այն ավելի հեշտ է դարձնում ծրագրում օպտիմիզացիաների կատարումը և այն շատ ավելի նման է մեքենայական լեզվին, և հետևաբար ավելի դյուրին է նրանից դեպի մեքենայական լեզու թարգմանությունը։

Մեքենայական կոդի գեներացիա

Միջանկյալ կոդի թարգմանությունից հետո կոմպիլյատորը ծրագրում կատարում է որոշակի օպտիմիզացիաներ։ Օպտիմիզացիաների տեսակներից են օրինակ Code motion-ը, Sharing common subexpressions-ը, Loop unrolling-ը և այլն։

Դիտարկենք Code motion տեսակի օպտիմիզացիայի մի օրիակ։

while(n < 124) {
int k = 4;
n = n + 4;
}

Վերը նշված օրինակում k փոփոխականը ցիկլի ամեն քայլին նորից հայտարարվում է, այն ինչ այն կարող էր հայտարարվել while-ի վերևում: Code motion տեսակի օպտիմիզացիայի ընթացքում կոմպիլյատորը կատարում է նման տեսակի օպտիմիզացիաներ։

Այս ամենի կատարումից հետո տեղի է ունենում արդեն միջանկյալ կոդի թարգմանությունը դեպի տվյալ օպերացիոն համակարգին և համակարգչի պրոցեսորին սպեցիֆիկ Assembly ծրագրավորման լեզվի, որը սակայն նույնպես չի հանդիսանում մեքենայական լեզու։

Վերջնական մեքենայական լեզվի թարգմանությունն արդեն կատարվում է Assembler ծրագրի միջոցով, որը արդեն թարգմանված Assembly լեզվով գրված ծրագիրը թարգմանում է պրոցեսորին հասկանալի հրամանների հաջորդականության։

Code Republic-ը ծրագրավորման գիտահետազոտական կենտրոն է, որն ունի նաև ուսումնական բաժին։ Ուսումնական բաժնում խմբավորում ենք խորացված ծրագրավորումը մաթեմատիկայի, ֆիզիկայի և ինժեներության հետ։

Մենք ջանք ու ժամանակ չենք խնայում և ստեղծում ենք այնպիսի որակյալ նյութեր, որոնք ցույց են տալիս ծրագրավորման իրական կողմը` արվեստը: Առայժմ դա ստացվում է, իսկ պատճառը պարզ է.

մենք սիրում ենք այն, ինչ անում ենք։

Ձգտում ենք ունենալ ծրագրավորման, մաթեմատիկայի, ֆիզիկայի և ինժեներության խորացված լավագույն դասընթացները և վարձավճարը սահմանել ամսական հնարավոր նվազագույնը` 42 000 դրամ։ Խոստանում ենք երբեք չթանկացնել, իսկ շատ ու շատ անվճար դասընթացներ էլ տեղադրել YouTube-յան մեր ալիքում, այստեղ՝

Բոլոր ցանկացողները կարող են ստեղծել և տեղադրել նոր դասընթացներ, կամ, ինչու ոչ, գրել հայալեզու հոդվածներ Medium-ում։ Համագործակցության համար գրեք մեզ contact@coderepublic.am հասցեով։ Եվ, իհարկե, հետևեք մեզ այլ սոց. ցանցերում. Facebook, Instagram, Telegram, և որ ավելի կարևոր է՝ LinkedIn, տեղադրում ենք միայն օգտակար նյութեր։

Ջանք ու եռանդ չենք խնայում լուծելու երկրում գլխավոր խնդիրներից մեկը՝ որակյալ ծրագրավորող-ինժեներների կրթումը։ Ժամանակատար է, դժվար է, բայց կանգ չենք առնում։

Ընտրել ենք բա՛րդ ճանապարհը

--

--