Кіріспе
Компьютерлік бағдарлама, бір бағдарламалау тілінен екінші бағдарламалау тіліне кодты аударады. Компьютерлік есепте компилятор – бір бағдарламалау тілінде (көз тілі) жазылған компьютерлік кодты екінші тілге (мақсат тіліне) аударатын компьютерлік бағдарлама. "Компилятор" атауы көбінесе жоғары деңгейдегі бағдарламалау тілінен төмен деңгейдегі бағдарламалау тіліне (мысалы, ассемблер, нысандық код немесе машиналық код) көз кодын аударатын бағдарламаларға қолданылады, осы арқылы орындалатын бағдарлама жасалады. Әртүрлі пайдалы форматтарда шығыс беретін көптеген түрлі компиляторлар бар. Кросс-компилятор өзі іске қосылатын процессор немесе операциялық жүйеден өзге процессор немесе операциялық жүйе үшін код жасайды. Бутстрап компиляторы көбінесе уақытша компилятор болып табылады, ол тіл үшін тұрақтырақ немесе жақсырақ оңтайландырылған компиляторды компиляциялау үшін қолданылады. Байланысты бағдарламалық құралдарға декомпиляторлар (төмен деңгейлі тілдерден жоғары деңгейлі тілдерге аударатын бағдарламалар), көзден көзге компиляторлар немесе транспайлерлер (жоғары деңгейлі тілдер арасында аударатын бағдарламалар), тілді қайта жазушылар (әдетте, тілді өзгертпей өрнектердің пішінін аударатын бағдарламалар) және компиляторларды (немесе олардың бөліктерін) жасайтын компиляторлар кіреді, көбінесе оларды әртүрлі компиляторларды жасауға мүмкіндік беретін жалпы және қайта пайдалануға болатын тәсілмен. Компилятор келесі операциялардың бірін немесе барлығын орындайды, олар фазалар деп аталады: алдын ала өңдеу, лексикалық талдау, синтаксистік талдау, семантикалық талдау (синтаксис басқарылатын аударма), кіріс бағдарламаларын аралық өрнекке түрлендіру, кодты оңтайландыру және машинаға арналған кодты жасау. Компиляторлар әдетте осы фазаларды модульдік компоненттер ретінде жүзеге асырады, бұл тиімді жобалауға және көз кірісінен мақсатты шығысқа түрлендірудің дұрыстығына көмектеседі. Компилятордың дұрыс емес мінез-құлқынан туындаған бағдарламалық қателерді іздеу және оларды жою қиын болуы мүмкін; сондықтан компиляторды жасаушылар компилятордың дұрыстығын қамтамасыз ету үшін көп күш жұмсайды. Компиляторлар ғана емес, бастапқы бағдарламаларды түрлендіру үшін қолданылатын тілдік процессорлар бар. Интерпретатор – көрсетілген операцияларды түрлендіріп, орындайтын компьютерлік бағдарламалық құрал. Бэкюс-Наур формасы (BNF) тілдің "сөйлемдерінің" синтаксисін сипаттайды. Оны Джон Бэкюс әзірледі және Algol 60 синтаксисі үшін қолданды. Бұл идеялар тіл білімі маманы Ноам Чомскийдің контекстсіз грамматика тұжырымдамаларынан туындаған. "BNF және оның кеңейтімдері бағдарламалау нотацияларының синтаксисін сипаттау үшін стандартты құралға айналды. Көп жағдайда компиляторлардың бөліктері BNF сипаттамасынан автоматты түрде жасалады". 1942-1945 жылдар аралығында Конрад Цузе компьютерлер үшін алғашқы (алгоритмдік) бағдарламалау тілін жасады, ол Plankalkül ("Жоспарлау есептеуі") деп аталды. Цузе сондай-ақ бағдарламаның математикалық формуласын машинамен оқылатын перфорациялық пленкаға автоматты түрде аударуға арналған Planfertigungsgerät ("Жоспар құрастыру құрылғысы") туралы ойлады. APL – математикалық есептеулерге арналған тіл. 1949-1951 жылдар аралығында Хайнц Рутихаузер жоғары деңгейлі тіл және автоматты аудармашы болып табылатын Superplan ұсынды. COBOL (Common Business Oriented Language) бизнес-қосымшалар үшін басым жоғары деңгейлі тілге айналу үшін A0 және FLOW MATIC-тен дамыды. Символдық есептеуге арналған LISP (Тізімді өңдеу). Компилятор технологиясы цифрлық компьютер үшін жоғары деңгейдегі көз бағдарламасын төмен деңгейлі мақсатты бағдарламаға қатаң түрде түрлендіру қажеттілігінен пайда болды. Компиляторды көз кодын талдаумен айналысатын алдыңғы және талдауды мақсатты кодқа синтездеумен айналысатын артқы бөлік ретінде қарастыруға болады. Алдыңғы және артқы бөліктер арасындағы оңтайландыру тиімді мақсатты кодты жасайды. Компилятор технологиясының дамуындағы кейбір маңызды кезеңдер: 1952 жылдың мамыр айы: Ремингтон Рендтегі Грейс Хоппердің командасы A0 бағдарламалау тілі үшін компиляторды жазды (және оны сипаттау үшін "компилятор" терминін қолданды), бірақ A0 компиляторы толық компилятордың қазіргі түсінігіне қарағанда жүктеуші немесе байланыстырушы ретінде жұмыс істеді. 1952 жыл, қыркүйектен бұрын: Манчестер университетіндегі Манчестер Mark I компьютері үшін Алик Гленни жасаған Autocode компиляторы кейбір мамандар тарапынан алғашқы компиляцияланған бағдарламалау тілі деп есептеледі. 1954-1957 жылдар: Джон Бэкюс басқарыған IBM командасы FORTRAN-ды жасады, ол әдетте алғашқы жоғары деңгейлі тіл деп есептеледі. 1957 жылы олар FORTRAN компиляторын аяқтады, ол алғашқы толыққанды компиляторды жасады деп есептеледі. 1959 жыл: Дерек жүйелері тілі жөніндегі конференция (CODASYL) COBOL әзірлеуді бастады. COBOL дизайны A0 және FLOW MATIC-ке сүйенді. 1960-жылдардың басында COBOL бірнеше архитектураларда компиляцияланды. 1958-1960 жылдар: Algol 58, ALGOL 60-тың алдындағысы болды. Ол құрылымдық бағдарламалаудың дамуында маңызды қадам болған кодтық блоктарды енгізді. ALGOL 60 лексикалық ауқыммен ұялатылған функциялар анықтамаларын жүзеге асырған алғашқы тіл болды. Ол рекурсияны қамтыды. Оның синтаксисі BNF арқылы анықталды. ALGOL 60 одан кейін дамыған көптеген тілдерге әсер етті. Тони Хоар былай деді: "Бұл оның алдыңғыларынан ғана емес, сондай-ақ көптеген ізбасарларынан да жақсырақ болды". 1958-1962 жылдар: Джон Маккарти MIT-де LISP-ті жасады. Символды өңдеу мүмкіндіктері жасанды интеллект зерттеуі үшін пайдалы мүмкіндіктерді ұсынды. 1962 жылы LISP 1.5 шығарылымында бірнеше құралдарды атады: Стивен Рассел мен Дэниел Дж. Эдвардс жазған интерпретатор, Тим Харт пен Майк Левин жазған компилятор және ассемблер. Алғашқы операциялық жүйелер мен бағдарламалық құралдар ассемблер тілінде жазылған. 1960-жылдардың және 1970-жылдардың басында жүйелік бағдарламалау үшін жоғары деңгейлі тілдерді қолдану ресурстардың шектеулі болуына байланысты әлі де даулы болды, бірақ бірнеше зерттеу және өнеркәсіптік күш-жігерлер жоғары деңгейлі жүйелік бағдарламалау тілдеріне қарай өтуді бастады, мысалы, BCPL, BLISS, B және C. BCPL (Basic Combined Programming Language) 1966 жылы Кембридж университетіндегі Мартин Ричардс жасады, бастапқыда компилятор жасау құралы ретінде әзірленді. Бірнеше компиляторлар жасалды, Ричардстың кітабы тіл және оның компиляторы туралы түсініктер береді. BCPL ғана емес, әлі де зерттеуде қолданылатын ықпалды жүйелік бағдарламалау тілі болды, сонымен қатар B және C тілдерінің дизайнына негіз болды. BLISS (Basic Language for Implementation of System Software) W. A. Wulf басқаратын Карнеги Меллон университетінің (CMU) зерттеу тобы Digital Equipment Corporation (DEC) PDP 10 компьютері үшін жасады. CMU тобы бір жылдан кейін 1970 жылы BLISS 11 компиляторын жасады. Multics (Multiplexed Information and Computing Service), уақытты бөлісумен жұмыс істейтін операциялық жүйе жобасы, MIT, Bell Labs, General Electric (кейінірек Honeywell) қатысты және MIT-тен Фернандо Корбато басқарды. Multics IBM және IBM пайдаланушылар тобымен әзірленген PL/I тілінде жазылған. IBM-ның мақсаты бизнес, ғылыми және жүйелік бағдарламалау талаптарын қанағаттандыру болды. Талқылауға болатын басқа тілдер де болды, бірақ PL/I ең толық шешімді ұсынды, тіпті ол әлі іске асырылмаған болса да. Multics жобасының алғашқы бірнеше жылдарында тілдің кіші жиынтығы алдыңғы PL/I (EPL) компиляторымен ассемблер тіліне компиляцияланды, оны Дуг МакИлори мен Боб Моррис Bell Labs-тен жасады. EPL толық PL/I үшін бутстрап компиляторы жасалғанша жобаны қолдады. Bell Labs 1969 жылы Multics жобасынан шықты және BCPL тұжырымдамаларына негізделген жүйелік бағдарламалау тілі B жасады, оны Деннис Ричи және Кен Томпсон жазды. Ричи B үшін бутстрап компиляторын жасады және PDP 7 үшін Unics (Uniplexed Information and Computing Service) операциялық жүйесін B-де жазды. Unics ақырында Unix деп аталды. Bell Labs B және BCPL негізінде C дамыту және кеңейтуді бастады. BCPL компиляторы Bell Labs-пен Multics-ке тасымалданды және BCPL Bell Labs-те басымды тіл болды. Бастапқыда Bell Labs-тің B компиляторына алдыңғы бағдарлама C компиляторы жасалғанда қолданылды. 1971 жылы жаңа PDP 11 ресурсты...
software to translate computer languages
In computing, a compiler is a computer program that translates computer code written in one programming language (the source language) into another language (the target language). The name "compiler" is primarily used for programs that translate source code from a high level programming language to a low level programming language (e. g. assembly language, object code, or machine code) to create an executable program. There are many different types of compilers which produce output in different useful forms. A cross compiler produces code for a different CPU or operating system than the one on which the cross compiler itself runs. A bootstrap compiler is often a temporary compiler, used for compiling a more permanent or better optimised compiler for a language. Related software include decompilers, programs that translate from low level languages to higher level ones; programs that translate between high level languages, usually called source to source compilers or transpilers; language rewriters, usually programs that translate the form of expressions without a change of language; and compiler compilers, compilers that produce compilers (or parts of them), often in a generic and reusable way so as to be able to produce many differing compilers. A compiler is likely to perform some or all of the following operations, often called phases: preprocessing, lexical analysis, parsing, semantic analysis (syntax directed translation), conversion of input programs to an intermediate representation, code optimization and machine specific code generation. Compilers generally implement these phases as modular components, promoting efficient design and correctness of transformations of source input to target output. Program faults caused by incorrect compiler behavior can be very difficult to track down and work around; therefore, compiler implementers invest significant effort to ensure compiler correctness. Compilers are not the only language processor used to transform source programs. An interpreter is computer software that transforms and then executes the indicated operations. Backus–Naur form (BNF) describes the syntax of "sentences" of a language. It was developed by John Backus and used for the syntax of Algol 60. The ideas derive from the context free grammar concepts by linguist Noam Chomsky. "BNF and its extensions have become standard tools for describing the syntax of programming notations. In many cases, parts of compilers are generated automatically from a BNF description." Between 1942 and 1945, Konrad Zuse designed the first (algorithmic) programming language for computers called Plankalkül ("Plan Calculus"). Zuse also envisioned a Planfertigungsgerät ("Plan assembly device") to automatically translate the mathematical formulation of a program into machine readable punched film stock. APL is a language for mathematical computations. Between 1949 and 1951, Heinz Rutishauser proposed Superplan, a high level language and automatic translator. COBOL (Common Business Oriented Language) evolved from A 0 and FLOW MATIC to become the dominant high level language for business applications. LISP (List Processor) for symbolic computation. Compiler technology evolved from the need for a strictly defined transformation of the high level source program into a low level target program for the digital computer. The compiler could be viewed as a front end to deal with the analysis of the source code and a back end to synthesize the analysis into the target code. Optimization between the front end and back end could produce more efficient target code. Some early milestones in the development of compiler technology:
May 1952: Grace Hopper's team at Remington Rand wrote the compiler for the A 0 programming language (and coined the term compiler to describe it), although the A 0 compiler functioned more as a loader or linker than the modern notion of a full compiler. 1952, before September: An Autocode compiler developed by Alick Glennie for the Manchester Mark I computer at the University of Manchester is considered by some to be the first compiled programming language. 1954–1957: A team led by John Backus at IBM developed FORTRAN which is usually considered the first high level language. In 1957, they completed a FORTRAN compiler that is generally credited as having introduced the first unambiguously complete compiler. 1959: The Conference on Data Systems Language (CODASYL) initiated development of COBOL. The COBOL design drew on A 0 and FLOW MATIC. By the early 1960s COBOL was compiled on multiple architectures. 1958–1960: Algol 58 was the precursor to ALGOL 60. It introduced code blocks, a key advance in the rise of structured programming. ALGOL 60 was the first language to implement nested function definitions with lexical scope. It included recursion. Its syntax was defined using BNF. ALGOL 60 inspired many languages that followed it. Tony Hoare remarked: " it was not only an improvement on its predecessors but also on nearly all its successors." 1958–1962: John McCarthy at MIT designed LISP. The symbol processing capabilities provided useful features for artificial intelligence research. In 1962, LISP 1.5 release noted some tools: an interpreter written by Stephen Russell and Daniel J. Edwards, a compiler and assembler written by Tim Hart and Mike Levin. Early operating systems and software were written in assembly language. In the 1960s and early 1970s, the use of high level languages for system programming was still controversial due to resource limitations. However, several research and industry efforts began the shift toward high level systems programming languages, for example, BCPL, BLISS, B, and C.
BCPL (Basic Combined Programming Language) designed in 1966 by Martin Richards at the University of Cambridge was originally developed as a compiler writing tool. Several compilers have been implemented, Richards' book provides insights to the language and its compiler. BCPL was not only an influential systems programming language that is still used in research but also provided a basis for the design of B and C languages. BLISS (Basic Language for Implementation of System Software) was developed for a Digital Equipment Corporation (DEC) PDP 10 computer by W. A. Wulf's Carnegie Mellon University (CMU) research team. The CMU team went on to develop BLISS 11 compiler one year later in 1970. Multics (Multiplexed Information and Computing Service), a time sharing operating system project, involved MIT, Bell Labs, General Electric (later Honeywell) and was led by Fernando Corbató from MIT. Multics was written in the PL/I language developed by IBM and IBM User Group. IBM's goal was to satisfy business, scientific, and systems programming requirements. There were other languages that could have been considered but PL/I offered the most complete solution even though it had not been implemented. For the first few years of the Multics project, a subset of the language could be compiled to assembly language with the Early PL/I (EPL) compiler by Doug McIlory and Bob Morris from Bell Labs. EPL supported the project until a boot strapping compiler for the full PL/I could be developed. Bell Labs left the Multics project in 1969, and developed a system programming language B based on BCPL concepts, written by Dennis Ritchie and Ken Thompson. Ritchie created a boot strapping compiler for B and wrote Unics (Uniplexed Information and Computing Service) operating system for a PDP 7 in B. Unics eventually became spelled Unix. Bell Labs started the development and expansion of C based on B and BCPL. The BCPL compiler had been transported to Multics by Bell Labs and BCPL was a preferred language at Bell Labs. Initially, a front end program to Bell Labs' B compiler was used while a C compiler was developed. In 1971, a new PDP 11 provided the resource to define extensions to B and rewrite the compiler. By 1973 the design of C language was essentially complete and the Unix kernel for a PDP 11 was rewritten in C. Steve Johnson started development of Portable C Compiler (PCC) to support retargeting of C compilers to new machines. Object oriented programming (OOP) offered some interesting possibilities for application development and maintenance. OOP concepts go further back but were part of LISP and Simula language science. Bell Labs became interested in OOP with the development of C++. C++ was first used in 1980 for systems programming. The initial design leveraged C language systems programming capabilities with Simula concepts. Object oriented facilities were added in 1983. The Cfront program implemented a C++ front end for C84 language compiler. In subsequent years several C++ compilers were developed as C++ popularity grew. In many application domains, the idea of using a higher level language quickly caught on. Because of the expanding functionality supported by newer programming languages and the increasing complexity of computer architectures, compilers became more complex. DARPA (Defense Advanced Research Projects Agency) sponsored a compiler project with Wulf's CMU research team in 1970. The Production Quality Compiler Compiler PQCC design would produce a Production Quality Compiler (PQC) from formal definitions of source language and the target. PQCC tried to extend the term compiler compiler beyond the traditional meaning as a parser generator (e. g., Yacc) without much success. PQCC might more properly be referred to as a compiler generator. PQCC research into code generation process sought to build a truly automatic compiler writing system. The effort discovered and designed the phase structure of the PQC. The BLISS 11 compiler provided the initial structure. The phases included analyses (front end), intermediate translation to virtual machine (middle end), and translation to the target (back end). TCOL was developed for the PQCC research to handle language specific constructs in the intermediate representation. Variations of TCOL supported various languages. The PQCC project investigated techniques of automated compiler construction. The design concepts proved useful in optimizing compilers and compilers for the (since 1995, object oriented) programming language Ada. The Ada STONEMAN document formalized the program support environment (APSE) along with the kernel (KAPSE) and minimal (MAPSE). An Ada interpreter NYU/ED supported development and standardization efforts with the American National Standards Institute (ANSI) and the International Standards Organization (ISO). Initial Ada compiler development by the U. S. Military Services included the compilers in a complete integrated design environment along the lines of the STONEMAN document. Army and Navy worked on the Ada Language System (ALS) project targeted to DEC/VAX architecture while the Air Force started on the Ada Integrated Environment (AIE) targeted to IBM 370 series. While the projects did not provide the desired results, they did contribute to the overall effort on Ada development. Other Ada compiler efforts got underway in Britain at the University of York and in Germany at the University of Karlsruhe. In the U. S., Verdix (later acquired by Rational) delivered the Verdix Ada Development System (VADS) to the Army. VADS provided a set of development tools including a compiler. Unix/VADS could be hosted on a variety of Unix platforms such as DEC Ultrix and the Sun 3/60 Solaris targeted to Motorola 68020 in an Army CECOM evaluation. There were soon many Ada compilers available that passed the Ada Validation tests. The Free Software Foundation GNU project developed the GNU Compiler Collection (GCC) which provides a core capability to support multiple languages and targets. The Ada version GNAT is one of the most widely used Ada compilers. GNAT is free but there is also commercial support, for example, AdaCore, was founded in 1994 to provide commercial software solutions for Ada. GNAT Pro includes the GNU GCC based GNAT with a tool suite to provide an integrated development environment. High level languages continued to drive compiler research and development. Focus areas included optimization and automatic code generation. Trends in programming languages and development environments influenced compiler technology. More compilers became included in language distributions (PERL, Java Development Kit) and as a component of an IDE (VADS, Eclipse, Ada Pro). The interrelationship and interdependence of technologies grew. The advent of web services promoted growth of web languages and scripting languages. Scripts trace back to the early days of Command Line Interfaces (CLI) where the user could enter commands to be executed by the system. User Shell concepts developed with languages to write shell programs. Early Windows designs offered a simple batch programming capability. The conventional transformation of these language used an interpreter. While not widely used, Bash and Batch compilers have been written. More recently sophisticated interpreted languages became part of the developers tool kit. Modern scripting languages include PHP, Python, Ruby and Lua. (Lua is widely used in game development.) All of these have interpreter and compiler support. "When the field of compiling began in the late 50s, its focus was limited to the translation of high level language programs into machine code The compiler field is increasingly intertwined with other disciplines including computer architecture, programming languages, formal methods, software engineering, and computer security." The "Compiler Research: The Next 50 Years" article noted the importance of object oriented languages and Java. Security and parallel computing were cited among the future research targets.
Компилятор құрылымы
Компилятор жоғары деңгейдегі бастапқы бағдарламаны төмен деңгейдегі мақсатты бағдарламаға формалды түрлендіруді іске асырады. Компиляторды жобалау толыққанды шешімді анықтауға немесе басқа компиляция құралдарымен, мысалы, алдын ала өңдеушілермен, құрастырушылармен, байланыстырғыштармен интерфейс жасайтын белгілі бір кіші жиынтықпен жұмыс істеуге мүмкіндік береді. Жобалау талаптары компилятор компоненттері арасындағы және қолдау құралдары жиынтығымен арасындағы қатаң анықталған интерфейстерді қамтиды. Бастапқы кезеңдерде компиляторды жобалауға қолданылған тәсіл өңделетін компьютер тілінің күрделілігіне, оны жобалаған адамның тәжірибесіне және қолданыстағы ресурстарға тікелей байланысты болды. Ресурстардың шектелуі бастапқы кодты бірнеше рет қарау қажеттілігіне әкелді. Бір адам жазған салыстырмалы түрде қарапайым тіл үшін компилятор бір монолиттік бағдарламалық құрал бола алады. Дегенмен, бастапқы тілдің күрделілігі артқан сайын, жобалау бір-біріне тәуелді бірнеше кезеңге бөлінуі мүмкін. Жеке кезеңдер компиляция процесіндегі функцияларға назар аудара отырып, жобалауды жақсартуға мүмкіндік береді.
Бір-жолақты және көп-жолақты компиляторлар
Компиляторларды өту саны бойынша жіктеу компьютерлердің аппараттық ресурстарының шектеулілігіне байланысты туындаған. Компиляция көп еңбек талап етеді және алғашқы компьютерлерде осы еңбектің бәрін атқаратын бір бағдарламаны сақтауға жеткілікті жад болмады. Осының салдарынан компиляторлар кішкентай бағдарламаларға бөлінді, олардың әрқайсысы бастапқы кодтан (немесе оның бір бейнесінен) өтіп, қажетті талдаулар мен аудармалардың бір бөлігін жүзеге асыратын. Бір рет өту арқылы компиляциялау мүмкіндігі классикалық түрде артықшылық ретінде қарастырылады, себебі ол компиляторды жазу жұмысын жеңілдетеді және бір рет өту арқылы компиляциялайтын компиляторлар көбінесе көп рет өту арқылы компиляциялайтындардан жылдам жұмыс істейді. Осылайша, алғашқы жүйелердің ресурстық шектеулерінің ықпалымен көптеген ерте тілдер бір рет өту арқылы компиляцияланатындай етіп әзірленді (мысалы, Паскаль). Кейбір жағдайларда тілдің мүмкіндігінің дизайны компилятордың бастапқы кодтан бірнеше рет өтуін қажет етуі мүмкін. Мысалы, 10-жолдағы түйіннің аудармасына әсер ететін 20-жолдағы жарияланымды қарастырайық. Бұл жағдайда, бірінші өтуде оларға әсер ететін түйіндерден кейін пайда болатын жарияланымдар туралы ақпарат жинақталуы керек, ал нақты аударма келесі өту кезінде жүзеге асырылады. Бір рет өту арқылы компиляциялаудың кемшілігі – жоғары сапалы кодты жасау үшін қажетті көптеген күрделі оптимизацияларды жүзеге асыру мүмкін емес. Оптимизациялайтын компилятордың қанша рет өтуін дәл санау қиын болуы мүмкін. Мысалы, оптимизацияның әртүрлі кезеңдері бір өрнекті бірнеше рет талдауы мүмкін, бірақ басқа өрнекті бір рет қана талдауы мүмкін. Компиляторды кішкентай бағдарламаларға бөлу – дәлелмен дұрыс компиляторларды жасауға қызығушылық танытқан зерттеушілер қолданатын әдіс. Кішкентай бағдарламалар жиынтығының дұрыстығын дәлелдеу көбінесе үлкен, біртұтас, баламалы бағдарламаның дұрыстығын дәлелдеуден аз күш-жігерді қажет етеді.
Үш сатылы компилятор құрылымы
Компиляторды құрастырудағы фазалардың нақты санына қарамастан, фазаларды үш кезеңнің біріне жатқызуға болады. Бұл кезеңдер: фронтенд, миддлтенд және бэкенд. Фронтенд кірісті сканерлеп, белгілі бір бастапқы тілге сәйкес синтаксистік және семантикалық дұрыстығын тексереді. Статикалық типтеу тілдерінде типтік ақпаратты жинақтап, типтік тексеруді жүргізеді. Егер кіріс бағдарламасы синтаксистік қатеге тап болса немесе типтік қатесі болса, ол қате және/немесе ескерту хабарламаларын шығарады, әдетте, қате анықталған бастапқы кодтың орнын көрсетеді; кейбір жағдайларда нақты қате бағдарламаның (әлдеқайда) бұрын болған болуы мүмкін. Фронтендтің құрамына лексикалық талдау, синтаксистік талдау және семантикалық талдау кіреді. Фронтенд кіріс бағдарламасын миддлтендпен одан әрі өңдеу үшін аралық өрнеуге (IR) түрлендіреді. Бұл IR әдетте бастапқы кодқа қарағанда бағдарламаның төменгі деңгейлі өрнеуі болып табылады. Миддлтенд мақсатты процессор архитектурасына тәуелсіз IR-де оптимизацияларды жүргізеді. Бұл бастапқы кодтан/машиналық кодтан тәуелсіздік, компилятордың әртүрлі тілдерді және процессорларды қолдайтын нұсқалары арасында жалпы оптимизацияларды пайдалануға мүмкіндік береді. Миддлтендтегі оптимизацияның мысалдары: пайдасыз кодты (өлі кодты жою) немесе қолжетпеуге болатын кодты (жетуді талдау) жою, тұрақты мәндерді табу және тарату (тұрақты тарату), есептеуді сирек орындалатын жерге жылжыту (мысалы, циклден тыс) немесе есептеуді контекстке сәйкес ету, нәтижеде "оптимизацияланған" IR шығарылады, ол бэкендпен қолданылады. Бэкенд миддлтендтен оптимизацияланған IR-ді қабылдайды. Ол мақсатты процессор архитектурасына тән қосымша талдаулар, түрлендірулер мен оптимизацияларды орындай алады. Бэкенд мақсатты құрастыру кодын жасайды, сонымен қатар регистрлерді бөлуді жүзеге асырады. Бэкенд нұсқауларды жоспарлайды, яғни нұсқауларды қайта реттейді, параллель орындалатын бірліктерді бос емес ұстау үшін кешіктіру ұяларын толтырады. Көптеген оптимизация мәселелері NP-қиын болғанымен, оларды шешуге арналған эвристикалық әдістер жақсы дамыған және өндірістік сападағы компиляторларда жүзеге асырылған. Әдетте, бэкендтің шығысы белгілі бір процессор мен операциялық жүйеге арналған машиналық код болып табылады. Бұл фронтенд/миддлтенд/бэкенд тәсілі миддлтендтің оптимизацияларын бөлісе отырып, әртүрлі тілдер үшін фронтендтерді және әртүрлі процессорлар үшін бэкендтерді біріктіруге мүмкіндік береді. Бұл тәсілдің практикалық мысалдары: GNU Compiler Collection, Clang (LLVM негізіндегі C/C++ компиляторы) және Amsterdam Compiler Kit, олардың бірнеше фронтендтері, ортақ оптимизациялары және бірнеше бэкендтері бар.
Артқы жағы
Артқы бөлік CPU архитектурасына тән оптимизациялармен және кодты құрумен айналысады. Маңызды мысал – бұл қысқа нұсқаулар тізбектерін тиімдірек нұсқауларға қайта жазатын "көз тесігінен қарау" оптимизациясы. Кодты құру: түрлендірілген аралық тіл шығыс тіліне, әдетте жүйенің түпкілікті машина тіліне аударылады. Бұл ресурс пен жадты бөлу туралы шешімдерді қамтиды, мысалы, қай айнымалыларды тіркелгілерге және жадқа орналастыруды, сондай-ақ тиісті машиналық нұсқауларды олардың сәйкес адрестеу режимдерімен бірге таңдау және жоспарлау (Сethi–Ullman алгоритміне де қараңыз). Дебюгтеуді жеңілдету үшін дебюгтеу деректерін жасау қажет болуы мүмкін.
Компилятордың дұрыстығы
Компилятордың дұрыстығы – компилятордың тілдік сипаттамасына сәйкес жұмыс істейтінін дәлелдеуге бағытталған бағдарламалық инженерия саласы. Бұл үшін ресми әдістерді қолдана отырып компиляторды жасау, сондай-ақ қолданыстағы компиляторды қатаң сынау (әдетте компиляторды тексеру деп аталады) сияқты тәсілдер қолданылады.
Жиналған және аударған тілдер
Жоғары деңгейдегі бағдарламалау тілдері әдетте аударма түрін ескере отырып жасалады: компиляцияланатын немесе интерпретацияланатын тіл ретінде. Дегенмен, практикада, тілдің тек компиляциялануын немесе тек интерпретациялануын талап ететін ештеңе сирек кездеседі, бірақ орындау кезінде қайта интерпретацияға негізделген тілдерді жобалау мүмкін. Мұндай жіктеу әдетте тілдің ең танымал немесе кең таралған нұсқаларын көрсетеді. Мысалы, BASIC кейде интерпретацияланған тіл деп аталады, ал C – BASIC компиляторлары мен C интерпретаторларының болуына қарамастан, компиляцияланған тіл. Интерпретация толыққанды компиляцияны алмастырмайды. Ол оны пайдаланушыдан жасырып, бірте-бірте жүзеге асырады. Интерпретатордың өзі интерпретацияланса да, орындалу стегінің төменгі жағында тікелей орындалатын машиналық нұсқаулар жиынтығы қажет (машина тіліне қараңыз). Сонымен қатар, оңтайландыру үшін компиляторлар интерпретатор функционалдығын қамтуы мүмкін, ал интерпретаторларға алдын ала компиляциялау әдістері енгізілуі мүмкін. Мысалы, егер өрнекті компиляция кезінде орындауға болып, нәтижелерді шығару бағдарламасына қосуға болады, онда ол бағдарлама әр орындалған сайын қайта есептеуді болдырмайды, бұл соңғы бағдарламаның жылдамдығын арттырады. Қазіргі заманғы дереу компиляциялау (just-in-time compilation) және байт-кодты интерпретациялау тенденциялары компиляторлар мен интерпретаторлардың дәстүрлі жіктелуін одан әрі бұлыстырады. Кейбір тілдік сипаттамаларда нұсқалар компиляция құралын қамтуы тиіс делінеді, мысалы, Common Lisp. Алайда, Common Lisp анықтамасында оны интерпретациялауға кедергі келтіретін ештеңе жоқ. Басқа тілдерде интерпретаторда іске асыру өте оңай, бірақ компиляторды жазуды әлдеқайда қиындататын мүмкіндіктер бар; мысалы, APL, SNOBOL4 және көптеген сценарийлік тілдер бағдарламаларға жүйелі жол операциялары арқылы орындалу кезінде кездейсоқ бастапқы кодты құруға мүмкіндік береді, содан кейін оны арнайы бағалау функциясына жіберу арқылы орындайды. Мұндай мүмкіндіктерді компиляцияланған тілде іске асыру үшін бағдарламаларға әдетте компилятордың өзінің нұсқасын қамтитын орындалу уақыты кітапханасы қосылуы керек.