Կոմպիլյատորի կառուցումը

Ինֆորմատիկայում **կոմպիլյատորի կառուցում** (), ոլորտ է, որը գործ ունի ծրագրավորման լեզուների մշակաման գործելակերպի, թեորեմների և դրանց հետ կապված կոմպիլյատորների հետ։

## Կոմպիլյատորներ

**Կոմպիլյատորը** ծրագիր է, որը կարդում է  ծրագրի տեքստը, գրված ինչ որ սկզբնական լեզվով և այն տրանսյացնում (թարգմանում) է այլ լեզվի՝ նշանակային(ելքային) էկվիվալենտ տեքստի։ Կոմպիլյատորի կարևոր դերերից մեկը այն է, որ տեղեկացնի սկզբնական ծրագրի սխալների մասին, տրանսլյացիայի գործընթացում հայտնաբերված։ 
thumb|center|upright=6.25|Կոմպիլյատոր
Եթե նշանակային ծրագիրը իրենից ներկայացնում է մեքենայակն լեզվով ծրագիր, այն կարող է օգտագործողի կողմից կանչվել, որոշակի մուտքային տվյալների մշակաման և որոշ ելքային տվյալների ստացման համար։
 thumb|center|upright=6.25|Նշանակային ծրագրի կատարումը

**Ինտերպրետատորը** իրենից ներկայացնում է պրեցեսսորի լեզվային ևս մեկ հասարակ տեսք։ Նշանակյին ծրագրի սացման փոխարեն ինտերպրեատաորը անմիջապես կատարում է սկզբանական ծրագրում գտնված օպերացիանեը։
thumb|center|upright=6.25|Ինտերպրետատոր

### Օրինակ
Java լեզվային պրոցեսորը իրենում միավորում է և կոմպիլյացիա և ինտերպրետացիա։ Java-ի սկզբանական ծրագիրը կարող է սկզբից կոմպիլյացվել միջանկյալ կոդի, ունենալով բայթկոդ։ Հետո բայթկոդը ինտերպրետացվում է վիրտուալ մեքենայի կողմից։ Այս մոտեցման առավելությունն այն է, որ բայթկոդը կոմպիլյացված ինչ քր մեքենայի կողմից կարող է կատարվել այլ մեքենայում։

Մուտքային տվյալների ավելի արագ մշակման համար Java-ի որոշ կոմպիլյատորներ, ուեն '''JIT կոմպիլյատորներ''', բայթկոդը տրանսլյացնում են մեքենայական կոդի անմիջապես միջանկյալ ծրագիրը սկսվելուց առաջ, մուտքային տվյալների մշակման համար։
thumb|center|upright=6.25|հիբրիդային կոմպիլյատոր
Կոմպիլյատորից բացի կատարվող նշանակային ծրագրի ստեղծման համար կարող են պահանջվել այլ ծրագրեր ևս։ Սկզբանակն ծրագիրը կարող է բաժանվել մոդուլների՝ տարբեր ֆայլերում գտնվող։ Սկզբանակն ծրագրի հավաքումը վստահվում է նախապրոցեսսորի կողմից ունեցած առանձին ծրագրերի։
thumb|center|upright=6.25|Լեզվի մշակման համակարգ
Ձևափոխված սկզբնական ծրագիրը հետո փոխանցվում է կոմպիլյատորին։ Կոմպիլյատորը կարող է որպես ելքային ծրագիր ասսեմբլերի լեզվով տալ, քանի որ ասսեմբլերի կոդը ավելի հեշտ է ստեղծել և կարգաբերել(debug)։ Այնուհետև ասսեմբլերի լեզուն մշակվում է այնպիսի ծրագրով, որը կոչվում է *ասսեմբլեր*, և որպես ելք տալիս է տալիս է տեղափոխելի կոդ։

Մեծ ծրագրերը հաճախ մասերով են կոմպիլյացվում, այնպես որ տեղափեխելի մեքենայակն կոդը պետք է կազմվի համատեղ այլ տեղափոխելի օբյեկտային ֆայլերի և կոդում գրադարանային ֆայլերի հետ միասին։ Լինկերը կատարում է արտաքին հիշողության հասցեների թույլատրում, որոցով կոդը մի ֆայլից կարող է դիմել այլ ֆայլի ինֆորմացիայի։ Այնուհետև բեռնիչը կատարման համար տեղափոխում է բոլոր կատարվող օբյեկտային ֆայլերը հիշողության մեջ։

## Հիմնական փուլերը
Կոմպիլյատորի կառուցման դասական սխեման բաժանվում է հետևյալ փուլերի․
* Բառային (լեքսիկական) վերլուծություն, 
* Շարահյուսական վերլուծություն, 
* Իմաստաբանական կամ իմաստային (սեմանտիկ) վերլուծություն, 
* Միջանկյալ կոդի գեներացիա, 
* Կոդի օպտիմիզացիա, 
* Նպատակային կոդի գեներացիա։

## Կոմպիլյատորի կառուցվածքը
thumb|center|upright=2.25| Ծրագրի թարգմանման փուլերը

Կոմպլյատորը բաղկացած է երկու մասերից վերլուծությունից և սինթեզից։

#### Վերլուծություն'''։'''
**Վերլուծությունը** ծրագիրը բաժանում է բաղադրյալ մասերի և դրանց վրա վերադրում է քերականական կառուցավածք։ Այնուհետև այն օգտագործում է այդ կառուցավծքը սկզբնական ծրագրի միջանկյալ ներկայացման ստեղծման համար։ Եթե անալիզը հայտնաբերում է, որ սկզբնական ծրագիրը շարահյուսապես սխալ է կազմված կամ իմաստապես թերի է, այն պետք է տեղեկացնի սխալի մասին, որ օգտագործողը կարողանա ուղղել հայտնաբերված սխալները։ Վերլուծությունը նաև հավաքում է սկզբնական ծրագրի մասին տեղեկատվություն և պահպանում է իր տվյալների տիպերը, ունենալով սիմվոլների աղյուսակներ, որը փոխանցվում է միջանկայալ ներկայացման սինթեզի հետ միասին։

#### Սինթեզ
**Սինթեզը** միջանկյալ ներկայացման հիման վրա կառուցում է պահանջվող նշանակային ծրագիրը և սիմվոլների աղյուսակից ինֆորմացիաներ։ Վերլուծությունը հաճախ անվանում են նախնական փուլ(**front end**), իսկ սինթեզը եզրափակիչ փուլ(**back end**)։

Եթե կոմպիլյացիայի գործընթացը ավելի մանրամասն դիտարկենք, ապա կտեսնենք որ այն իրենից ներկայացնում է *փուլերի* հաջորդականություն, որոնցից յուրաքանչյուրը փոխակերպում է սկզբնական ծրագրի ներկայացումներից մեկը ուրիշով։ 
thumb|center|upright=6.25|Կոմպիլյատորի փուլերը
Որոշ փուլեր կաորղ են միավորվել, իսկ միջփուլային միջանկյալ ներկայացումները կարող են չկառուցվել ակնհայտ։ Սիմվոլների հաջորդականությունը, որում պահվում են սկզբանակն ծրագրի բոլոր ինֆորմացիաները, օգտագործվում են կոմպիլյատորի բոլոր փուլերում։

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

### Բառային վերլուծություն
thumb|left|upright=1.50|Բառային վերլուծություն
Բառային վերլուծությունը կոմպիլըացիայի առաջին փուլն է։ Բառային վերլուծության ժամանակ նիշ֊առ֊նիշ ընթերցվում է ծրագրի սկզբնական տեքստը, և այդ սիմվոլների խմբավորմամբ կառուցվում են *լեքսեմներ*, ապա այս լեքսեմներին համապատասխանեցվում են պիտակներ՝ *թոքեններ*։ Յուրաքանչյուր լեքսեմի համար անալիզատորը կառուցում է հետևյալ տեսքի ելքային թոքեն՝

( *թոքենի_անուն, ատրիբուտի_արժեք* )

Այն տրվում է հաջորդ փուլին՝ շարահյուսական վերլուծությանը։ Թոքենի առաջին կոմպոնենտը՝ *թոքենի_անուն, * իրենից ներկայացնում է շարահյուսական վերլուծության ժամանակ օգտագործվող աբստրակտ սիմվոլ, իսկ երկրորդ կոմպոնենտը՝ *ատրիբուտի_արժեք* ցույց է տալիս սիմվոլների աղյուսակի գրառմանը՝ համապատասխան տվյալ թոքենին։ Սիմվոլների աղյասակի գրառումից ինֆորմացիան անհարժեշտ է սեմանտիկական անալիզի և կոդի գեներացիայի համար։

##### Օրինակ
Ենթադրենք սկզբանական ծրագիրը ունի վերագրման հրահանգ՝

 position = initial + rate * 60

Այս վերագրման մեջ սիմվոլները կարող են խմբավորվել հաջորդ լեքսեմներում և ցույց տան շարահյուսական վերլուծությանը փոխանցված հաջորդ թոքենները։ 
# ***position'''-ը'' իրենից ներկայացնում է լեքսեմ, որը կարող է վերածվել ''('''id''', 1)'' թոքենի, որտեղ ***id-ն*** աբստրակտ սիմվոլ է,  ցույց է տալիս իդենտիֆիկատոր, իսկ 1-ը ''position-ի'' համար ցույց է տալիս սիմվոլների աղյուսակում գրառումը։ Սիմվոլների աղյուսակում գրառումը որոշ իդենտիֆիկատորի համար պահպանում է իր մասին ինֆորմացիա, այնպիսին ինչպես անունը և տիպը։ 
# '''= վերագրման սիմվոլ'''ը իրենից ներկայացնում է լեքսեմ, որը ցուց է տալիս (=) թոքենը։ Քանի որ այդ թոքենը ատրիբուտի արժեքի կարք չունի, տվյալ թոքենի երկրորդ կոմպոնենտը բաց է թողված։ Որպես թոքենի անուն կարող է օգտագործվել ցանկացած աբստրակ սիմվոլ, օրինակ՝ assign, բայց հարմարավետության համար որպես աբստրակտ սիվոլի անուն օգտագործվում է այդ լեքսեման։ 
# ***initial** -ը'' իրենից ներկայացնում է լեքսեմա, որը ցուցադրվում է ''(**id**, 2)'' թոքենում, որտեղ 2-ը ''initial -ի'' համար ցույց է տալիս սիմվոլների աղյուսակի գրառումը։ 
# **+** լեքսեմ է հանդիսանում, ցուցադրվում է ''(+)'' թոքենում։ 
# ''rate՝ լեքսեմա է, '' ցուցադրված (***id*', 3*) թոքենում,  որտեղ 3-ը *rate՝-ի* համար ցույց է տալիս սիմվոլների աղյուսակի գրառումը։ 
# *'*** լեքսեմ է հանդիսանում, ցուցադրվում է ''(*)'' թոքենում։ 
# **60**՝ լեքսեմ է հանդիսանում, ցուցադրվում է ''(60)'' թոքենում։ 
Լեքսեմները բաժանող բացատները լեքսիկական անալիզատորով դեն են գցվում։

Լեքսիկական վերլուծությունից հետո լեքսեմների հաջորդականությունը ունի հետևյալ տեսքը՝

 id1 (=) id2 (+) id3 (*) (60)

Այս դեպքում =, +, * թոքենների անուների ներկայացումը իրենից ներկայացնում է աբստրակտ սիմվոլներ հավասարման, գումարման և բազմապատկման համար համապատասխանաբար։

=== Վերագրման հրամանի տրանսլյացիան ===
[[Պատկեր:Screenshot-turbo51.com 2016-01-14 17-04-56.png|thumb|center|upright=6.25| Վերագրման հրամանի տրանսլյացիան]]

=== Շարահյուսական վերլուծություն ===
[[Պատկեր:2—screenshot-turbo51.com 2016-01-14 23-16-01.png|thumb|left|upright=1.50|Շարահյուսական վերլուծություն]]
Շարահյուսական վերլուծությունը(parsing) կոմպիլյատորի երկրորդ փուլն է։ Շարահյուսական վերլուծության ժամանակ բառային վերլուծիչից ստացվող թոքենների հոսքին համապատասխանեցվում է լեզվի շարահյուսությամբ որոշվող կառուցվածք։ Այդ կառուցվածքը կարելի է արտահայտել, օրինակ, քերականական ծառերի (կամ աբստրակտ քերականական ծառերի) միջոցով, որում յուրաքանչյուր ներքին հանգույց ներկայացնում է գործողություն, իսկ երեխա հանգույցները այդ գործողությունների արգումենտներ։ Աբստրակտ քերականական ծառը այս ***id1 (=) id2 (+) id3 (*) (60)*** թոքենների հաջորդականության համար ունի «վերագրման հրամանի տրանսլյացիա» պատկերում ներկայացված տեսքը։

Այդ ծառը ցույց է տալիս հաջորդականություն, որում կատարվում է վերագրման գործողությունը։ Ծառը ունի ներքին հանգույց, պիտակավորված *, որի ձախ երեխան հանդիսանում է ''(**id**, 3)'', իսկ առաջինը՝ 60։ ''(**id**, 3)'' հանգույցը ներկայացնում է ''rate'' իդենտիֆիկատորը։ *-ով պիտակավորված հանգույցը բացահայտ ցուց է տալիս, որ սկզբից պետք է բազմապատկել ''rate'' և ''60'' արժեքները''։  + -''ով պիտակավորված հանգույցը ցուց է տալիս, որ պետք է բազմապատկման արդյուքը ավելացնել ''initial'' արժեքին։ Ծառի արմատի պիտակավորումը խոսում է այն մասին, որ պետք է այդ գումարման արդյուքը վերագրել հիշողության դիրքում, նշանակված որպես ''position'' իդենտիֆիկատոր''։'' Գործողությունների կատարման հերթականությունը համընկնում է մաթեմատիկական օրենքներին, որը խոսում է այն մասին, որ բազմապատկումը ունի ավելի բարձր առաջնահերթություն, քան գումարումը, և պետք է կատարված լինի մինչև գումարումը։

Կոմպիլյատորի հաւորդ փուլը օգտագործում է քերականական կառուցվածք, որը օգնում է նորից վերլուծել սկզբանական և գեներացված նշանակային ծրագիրը։ Ծրագրավորման լեզվում օգտագործվում է **context-free gramer** լեզվի քերականությունը սահմանելու համար։ Շարահյուսապես կառավարման որոշումը օգնում է հստակեցնել ծրագրավորման լեզվի նախագծման տրանսլյացիան։
 [[Պատկեր:Parsing-example.png||thumb|left|289px|արտահայտության վերլուծության ծառի օրինակ]]
Քերականությունը ծրագրավորման լեզվուները մշակողներին և կոմպիլյատոր սեղծողներին ապահովում է զգալի առավելություններ․
* Քերականությունը ծրագրավորման լեզվի համար տալիս է ճշգրիտ, միևնույն ժամանակ հասկանալու համար պարզ շարահյուսական հստակեցում։ 
* Քերականության որոշ դասերի համար հնարավոր է ավտոմատ կերպով կառուցել արդյունավետ շարահյուսական անալիզատոր, որը սահմանում է սկզբնական ծրագրի շարահյուսական կառուցվածքը։
* Անալիզատորի ավտոմատ ստեղծման լրացուցիչ առավելություն է հանդիսանում շարահյուսական անմիարժեքության և այլ բարդությունների հայտաբերելու հնարավորությունը, որոնք լեզուն և իր կոմպիլյատորի ստեղծման սկզբանական փուլում ի սկզբանե կարող են մնալ անտեսանելի։ 
* Քերականության ճշգրիտ կառուցումը ծրագրավորման լեզվին տալիս է այնպիսի կառուցվածք, որը նպաստում է սկզբանական ծրագրի տրանսլյացիայի թեթևացման և բացահայտում է սխալները։
* Քերականությունը թույլ է տալիս լեզվին իտերատիվ զարգանա՝ հարստանալով նոր կառուցվաածքներով նոր խնդիրներ լուծման համար։ Լեզվում նոր կառուցվածքները ավելացումը ավելի հեշտ խնդիր է դառնում, եթե լեզվի ներկայիս իրականցումը հիմնված է իր քերականական նկարագրության վրա։

=== Իմաստային վերլուծություն ===
[[Պատկեր:3—screenshot-turbo51.com 2016-01-14 23-16-37.png|thumb|left|upright=1.50|Իմաստային վերլուծություն]]
Իմաստային վերլուծությունը օգտագործում է շարահյուսական ծառ և սիմվոլների աղյուսակից ինֆորմացաիներ, ստուգելու համար սկզբանական ծրագրի իմաստային համաձայնեցվածությունը սահմանված լեզվի հետ։ Ինչպես նաև հավաքում է տիպերի մասին ինֆորմացիա և դա պահպանում է շարահյուսական ծառում կամ սիմվոլների աղյուսակում՝ միջանկյալ կոդի գեներացիայի գործընթացում հաջորդ օգտագործման համար։ Սեմանտիկ վերլուծության ժամանակ ստուգվում են ծրագրի իմաստային բաղադրիչները։ Օրինակ, անունների հայտարարման և օգտագործման համապատասխանությունը, գործողությունների օպերանդների տիպերի համապատասխանությունը և այլն։

Իմաստային վերլուծության կարևոր մաս է հանդիսանում ''տիպերի ստուգում'' ը, երբ կոմպիլյատորը ստուգում է, արդյոք բոլոր օպերատորները ունեն համապատասխան տիպի օպերանդներ։ Օրինակ, շատ ծրագրավորման լեզուներում պահանջվում է, որ զանգվածի ինդեքսը ունենա ամբողջ թիվ, կոմպիլյատորը պետք է տեղեկացնի սխալի մասին, եթե որպես ինդեքս օգտագործվել է սահող ստորակետով թիվ։

Լեզվի դասկարգումը կարող է լուծել սահմանված տիպերի փոխակերպումը։ Օրինակ բինար թվաբանական օպերատորը կարող է օգտագործվել կամ ամբողջ թվի զույգին կամ սահող ստորակետով թվի զույգին։ Եթե այդպիսի օպերատորը կրառվոում է ամբողջ և սահող ստորակետով թվին, ապա կոմպիլյատորը կարոզ է կատարել ամբողջ թվի փոխակերպում սահող ստորակետով թվի։

Այդպիսի փոխակերպում դիտարկված է «վերագրման հրամանի տրանսլյացիա» պատկերում։ Ենթադրենք, որ ''position-ը, initial-ը'' և ''rate-ը'' հայտարարվել են որպես սահող ստորակետով թվեր, և որ 60 լեքսեմը ամբողջ թիվ է։ Իմաստային վերլուծությունում տիպերի ստուգումը վերլուծում է որ * օպերատորին կիրառվում է ''rate'' սահող ստորակետով թիվ և ամբողջ թիվ 60-ը։ Այս դեպքում ամբողջ թիվը կարող է փոխակորպվել սահող ստորկետով թվի։ Իմաստային անալիզատորի ելքում ստացված սինտակսային ծառը վերը դիտարկված պատկերում ունի լրացուցիչ **inttofloat** հանգույց, որը բացահայտ ձևով փոխակերպում է ամբողջ արգումենտը։

=== Միջանկյալ կոդի գեներացիա ===
[[Պատկեր:4—screenshot-turbo51.com 2016-01-14 23-17-22.png|thumb|left|upright=1.50|Միջանկյալ կոդի գեներացիա]]
Սկզբնական ծրագրի տրանսլյացիան նշանակային կոդի կարող է ստեղծել մեկ կամ մի քանի տարբեր տեսքի միջանկյալ ներկայացումներ։ Շարահյուսական ծառը հանդիսանում է միջանկյալ ներկայացման տեսք, հիմնականում դրանք օգտագործվում են շարահյուսական և իմաստային վերլուծության գործընթացում։

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

Միջանկյալ կոդի գեներացիայի ելքը բաղկացած է եռհասցեանի կոդի հերթականությունից՝
 t1 = inttofloat (60)
 t2 - id3 * tl 
 t3 = id2 + t2 
 id1 = t3

Յուրաքանչյուր եռհասցեանի վերագրման հրաման աջից պարունակում է մինիմում մեկ օպերատոր։ Այդպիսով բերված հրամանները որոշում են գործողությունների կատարման հաջորդականությունը՝ սկզբանկան ծրագրում

 id1 (=) id2 (+) id3 (*) (60)

բազմապատկումը կատարվում է ավելի շուտ քան գումարումը։ Կոմպիլյատորը արժեքները պահելու համար պետք է գեներացնի ժամանակավոր անուններ։ Որոշ եռհասցեանի հրամաններ առաջինի և վերջինի նման պահում են երեքից քիչ օպերանդներ։

=== Կոդի օպտիմիզացիա ===
[[Պատկեր:5—screenshot-turbo51.com 2016-01-14 23-17-44.png|thumb|left|upright=1.50|Կոդի օպտիմիզացիա]]

Մեքենայից անկախ կոդի օպտիմիզացիայի փուլը փորձում է լավարկել միջանկյալ կոդը, որպեսզի ստանա ավելի որակյալ նշանակային կոդ։ Հիմնականում «ավելի որակյալ», «լավ» արտահայտությունները նշանակում են «ավելի արագ», բայց կարող են կիրառվել այլ կրիտերյաներ ևս, ինչպես օրինակ «ավելի կրճատ կոդ» կամ «կոդ, որը օգտագործում է ավելի քիչ ռեսուրսներ»։ 
 
Միջանկյալ կոդի պարզ գեներացիայի ալգորիթմը հաջորդող օպտիմիզացված կոդի հետ իրենից ներկայացնում է լավ նշանակային կոդի գեներացիայի ռացիոնալ մեթոդ։ Օպտիմիզատորը կարող է սահմանել, որ 60-ի ամբողջ թվի փոխակերպումը սահող ստորակոտով թվի կոմպիլյացիայի ժամանակ կարող է կատարված լինել մեկ անգամ, այպես որ **inttofloat** օպերացիան կարող է հեռացվել 60 ամբողջ թիվը 60․0 սահող ստորակետով թվի փոխարինելու ճանապարհով։ Բացի դրանից t3 -ը օգտագործվում է միայն մեկ անգամ՝ արժեքը id1 փոխանցելու համար, այնպես որ օպտիմիզատորը կարող է այս արտահայտությունը․
 
 t1 = inttofloat (60)
 t2 - id3 * tl 
 t3 = id2 + t2 
 id1 = t3

փոխակերպել ավելի կարճ հաջորդականության որը ունի հետևյալ տեսքը՝
 t1 = id3 * 60.0
 id1 = id2 + t1
Այսպես կոչված «օպտիմիզացված կոմպիլյատորները» այս փուլում շատ ժամանակ են ծախսում, այն դեպքում երբ այստեղ այլ կոմպիլյատորներ կիրառում են ավելի պարզ օպտիմիզացիայի մեթոդներ, որոնց գոյությունը բարձրացնում է նշանակային ծրագրի աշխատանքը, այդպիսիվ կոմպիլյացիայի գործընթացը շատ չեն դանդաղեցնում։

=== Կոդի գեներացիա ===
[[Պատկեր:5—screenshot-turbo51.com 2016-01-14 23-18-02.png|thumb|left|upright=1.50|Կոդի օպտիմիզացիա]]

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

Օրինակ օգտագործելով R1 և R2 ռեգիստորները միջանկյալ կոդ
 
 t1 = id3 * 60.0
 id1 = id2 + t1

կարող է տրանսլյացվել մեքենայակն կոդի հետևյալ ձևով՝

 LDF R2, id3 
 MULF R2, R2, #60.0 
 LDF R1, id2 (1.5) 
 ADDF R1, R1, R2 
 STF id1, R1

Յուրաքանչյուր հրամանի առաջին օպերանդը սահմանում է որպես ստացող (ընդունող)։ F-ը յուրաքանչյուր հրամանում խոսում է այն մասին, որ հրամանը աշխատում է սահող ստորակետով թվերի հետ։ Կոդը id3 հասցեն բեռնում է R2 ռեգիստրում, այնուհետև այն բազմապատկում է սահող ստորակետով հաստատունի հետ՝ 60.0։ **#*' ցույց է տալիս, որ 60․0-ն անհրաժեշտ է դիտարկել ինչպես անմիջական արժեք։ Երրորդ հրամանը տեղաձոխում է id2-ը R1 ռեգիստր, իսկ չորրորդը դրան ավելացնում է նախապես հաշվարված և պահպանված արժեքը R2 ռեգիստր։ R1 ռեգիստրի արժեքը պահվում է id1 հասցեում։
Սա կոդի գեներացիայի թեթև ներկայացումն է; Հիշողության բաշխման որոշումը կայացվում է, կամ միջանկյալ կոդի գեներացիայի, կամ նշանակային կոդի գեներացայի ընթացքում։

=== Սիմվոլների աղյուսակի կառավարումը ===
Կոմպիլյատորի կարևոր գործառույթ է համարվում սկզբանկան ծրագրում անունների փոփոխականներում գրելը և յուրաքանչյուր անունի տարբեր ատրիբուտների մասին ինֆորմացիայի կուտակումը։ Այդ ատրիբուտները կարող են տրամադրել տվյալ անվան համար ընտրված հիշողության մասին ինֆորմացիա(հատկապես ծրագրում որտեղ կարող է դրա արժեքը օգտագործվել) և պրոզեդուրաների անունների դեպքում, այնպիսի տեղեկություն, ինչպիսին է դրա արգումեների տիպերը և քանակը, յուրաքանչյուր արգումենտին փոխանցվող մեթոդը (օրինակ արժեքով կամ հղումով), ինչպես նաև վերադարձվող տիպը։
<br />
Սիմվոլների աղյուսակը իրենից ներկայացնում է տվյակների կառուցվածք, յուրաքանչյուր փոփոխականի անվան համար պահվող գրառումները։ տվյալների տիպերը պետք է մշակվեմ այնպես, որ կոմպիլյատորին թույլատրեն արագ գնել յուրաքանչյուր անվան գրառում, ինչպես նաև արագ պահպանել տվյալները գրառումներում և դրանք ստանա։

== Արտաքին հղումներ ==
* 
* [http://scheme2006.cs.uchicago.edu/11-ghuloum.pdf Incremental Approach to Compiler Construction]
* [http://la-samhna.de/library/compile/index.html Compile-Howto]
* *Basics of Compiler Design ''
* 
* 
* Let's Build a Compiler
* Forum about compiler development 

Կատեգորիա:Ծրագրավորման լեզուներ
Կատեգորիա:Ծրագրավորում