A fordítóprogram (angolul compiler) olyan számítógépes program, amely valamely programozási nyelven írt programot képes egy másik nyelv szabályaira lefordítani, például gépi kódra, köztes kódra vagy egy másik programozási nyelv kódjára. A fordítóprogram elnevezést első sorban olyan programokra használják, ahol a forráskód (source code) valamilyen magas szintű programozási nyelv (például C# vagy Java), a célnyelv pedig, amire a fordító lefordítja a programot, valamilyen alacsony szintű nyelv (pl. assembly vagy gépi kód), amelyek már futtatható kódok.
Sokféle különböző fordítóprogram létezik. Ha a lefordított program olyan számítógépen bír futni, aminek a CPU-ja vagy az operációs rendszere különbözik attól a számítógéptől, amin a fordítás végbement, akkor keresztirányú fordítóprogramról (cross compilerről) beszélünk. A bootstrap compiler olyan fordító, amit azon a nyelven írnak, amit le kíván fordítani. Azt a fordítót, ami alacsony szintű nyelvről magasabb szintű nyelvre fordít, kódvisszafejtő programnak (angolul decompiler) nevezik. Az a program, ami adott magas szintű programozási nyelvről egy másik magas szintű programozási nyelvre fordít, source-to-source compiler. Egy nyelv-újraíró olyan program, ami a kifejezések formáját nyelvváltoztatás nélkül hajtja végre. A fordító generátor compiler-compiler fogalom olyan programozó eszközt takar, amely elemzőt, értelmezőt vagy fordítót hoz létre a programozási nyelv és a gép formális leírása alapján.
Csoportosítás A fordítandó programot forrásprogramnak (nyelvét forrásnyelvnek), a lefordított programot tárgyprogramnak (nyelvét tárgynyelvnek) nevezzük.
E szerint a fordítóprogramokat a következőképp csoportosíthatjuk: natív kódra fordítók több platformra fordítók magas szintű nyelvből egy másik magas szintű nyelvre
Kivitelezés A fordítóprogram végrehajtja a formális átalakítást egy magas szintű forrásnyelvről egy alacsony szintű tárgynyelvre. A fordítókészlet meghatároz egy végponttól végpontba (end to end) megoldást, vagy kezelhet egy meghatározott részhalmazt, amely kapcsolódik más fordítási eszközökhöz pl. előfeldolgozókhoz (preprocessors), összeszerelőkhöz (assemblers), összekötőkhöz(linkers). A tervezési követelmények szigorúan meghatározott felületeket tartalmaznak mind a fordítóelemek mind pedig a támogató eszközök között.
Kezdetben a fordítók tervezésének megközelítését közvetlenül befolyásolták a feldolgozandó számítógépes nyelv összetettsége, a tervező személy(ek) tapasztalata és a rendelkezésre álló források. Az erőforrás-korlátozások szükségessé tették a forráskód többszöri áthaladását.
Egy viszonylag egyszerű nyelv fordítója, amelyet ember írt, lehet egyetlen monolitikus szoftver. Mivel azonban a forrásnyelv ettől bonyolultabbá válhat, a terv több egymástól függő fázisra bontható. Külön szakaszok biztosítják a tervezési fejlesztéseket, amelyek a fejlesztés a fordítási folyamat funkcióira összpontosítanak.
A fordítóprogramok két fázisban dolgozzák fel a kódot: az elsőben lefordítja a forráskódot egy közbeeső kódra (előrész) a második fázisban történik az úgynevezett fordítási eljárás. (hátrész)
Első fázis (Front End)
Ezt a fázist három nagy fázisra lehet bontani: lexikális elemzésre, szintaktikai elemzésre és szemantikai elemzésre.
A front end a forráskódot elemzi a program belső reprezentációjának és az ún. közbenső reprezentációnak (intermediate representation, IR) felépítéséhez. Ezen felül kezeli a szimbólumtáblát, egy adatszerkezetet amely leképzi a forráskód minden szimbólumát a kapcsolódó információkkal mint például a hely, típus és hatókört (scope).
Lexikális elemzés A forráskód tokenizálása, felbontása a szintaktikai elemzőnek értelmezhető szimbólumokká, azaz a nyers forrásszövegből kreál szimbólumsorozatot, általában operátorok, fenntartott szavak, azonosítók stb. formájában. A lexikai hibák általában elírásokból adódnak, ezeket legjobb tudásuk szerint elfedik az elemzők, sokszor kitalálva, mit is akarhatott írni a programozó.
Szintaktikai elemzés A nagyrészt környezetfüggetlen nyelvtan alapján felépíti a szintaxisfát, az esetleges hibákat tudása szerint átugorva.
Főbb fajtái az LL és az LR elemzők.
Szemantikai elemzés A dinamikus szemantika ellenőrzése történik ebben a szakaszban, típusellenőrzések, függvények paraméterszáma, típushelyessége, általában a programkód értelmessége. Míg a lexikális és a szintaktikus ellenőrzésre már igen jó automatizált eszközeink vannak, a szemantikus elemzést mindeddig nem sikerült általánosan és hatékonyan automatizálni.
Hátrész Itt történik a közbeeső kód lefordítása gépi kódra. Ez is több lépésből tevődik össze: optimizálás: opcionális, a közbeeső kód átalakítása kisebb és gyorsabb formába (a program kívülről látható működése ettől (többnyire) nem változik). Általában ezt már az assembly nyelvű kódon végzi a fordítóprogram. kódgenerálás: a gépi kód generálása. A mnemonikok egyszerű átfordítása gépi kóddá valamint a modulon belül feloldható hivatkozások feloldása, ugrási címkék kiszámítása.
Fordítóprogram vagy interpreter? A magas szintű programozási nyelven megírt programot futtatáshoz fordítóprogrammal lefordítjuk gépi kódra, vagy interpreterrel interpretárjuk, vagyis értelmezzük. Az első esetben ún. object code keletkezik, amiből szerkesztéssel lehet futtatható programot készíteni. A második esetben általában nem keletkezik futtatható program, legfeljebb egy tömör, mindenféle felesleges résztől mentes közbülső kód (néha ún. bytecode), amit az interpreter második fázisa végrehajt.
Történet A tudósok, matematikusok és mérnökök által kidolgozott elméleti számítási koncepciók képezték a digitális modern számítástechnika fejlesztésének alapját a második világháború idején. Az elsődleges bináris nyelvek azért fejlődtek ki, mert a digitális eszközök csak az egyeseket és a nullákat, valamint az alapjául szolgáló gépi architektúra áramkörmintáit értik meg. Az 1940-es évek végén assembly nyelveket hoztak létre, hogy a számítógépes architektúrák jobban kivitelezhetők legyenek. A korai számítógépek korlátozott memóriakapacitása komoly technikai kihívásokhoz vezetett az első fordító tervezésekor. Ezért a fordítási folyamatot több kisebb programra kellett felosztani. A felhasználói felületek programjai előállítják azokat az elemző termékeket, amelyeket a back end a célkód előállításához használnak. Ahogyan a számítógépes technológia több forrást biztosított, a fordítók jobban igazodhattak magához a fordítási folyamathoz.
A programozók számára általában hatékonyabb a magas szintű nyelv használata, így a magas szintű nyelvek fejlesztése a digitális számítógépek által kínált lehetőségekből fakad. A magas szintű nyelvek olyan formális nyelvek, amelyeket szintaxisuk és szemantikájuk szigorúan meghatároznak, és amelyek a magas szintű nyelvi architektúrát alkotják. Ezen formális nyelvek elemei a következők:
ábécé, bármilyen véges szimbólumkészlet; karakterlánc, a szimbólumok véges sorozata; nyelv, bármilyen karakterlánckészlet ábécében.
A mondatokat egy nyelvben meghatározhatja egy nyelvtannak nevezett szabálykészlet.
A Backus–Naur-forma (BNF) leírja a nyelv „mondatainak” szintaxisát, és John Backus az Algol 60 szintaxisához használta. Az ötletek Noam Chomsky, nyelvész, kontextus nélküli nyelvtani fogalmaiból származnak. "A BNF és annak kiterjesztései sztenderd eszközökké váltak a programozási jelölések szintaxisának leírására, és sok esetben a fordítók részeit automatikusan generálják a BNF leírásból."
Az 1940-es években Konrad Zuse egy algoritmikus programozási nyelvet készített Plankalkül ("Plan Calculus") néven. Noha az 1970-es évekig nem valósult meg a megvalósítás, a későbbiekben az APL-ben látott koncepciókat mutatta be, amelyeket Ken Iverson tervezett az 1950-es évek végén.A z APL egy nyelv matematikai számításokhoz.
A magas szintű nyelvtervezés a digitális számítástechnika kialakulási éveiben hasznos programozási eszközöket nyújtott számos alkalmazáshoz:
A mérnöki és tudományos alkalmazásokban használt FORTRAN (Formula Translation) tekinthető az első magas szintű nyelvnek. A COBOL (Common Business-Oriented Language) az A-0-ból és a FLOW-MATIC-ból alakult ki az üzleti alkalmazások domináns magas szintű nyelvévé. LISP (List Processor)szimbolikus számításhoz.
A fordítótechnika a magas szintű forrásprogram szigorúan meghatározott átalakításának szükségességéből fejlődött ki a digitális számítógép alacsony szintű célprogramjává. A fordítót előtérként lehet tekinteni a forráskód elemzésének kezelésére, és a back end az elemzés célkódba történő szintetizálására. A front end és a back end közötti optimalizálás hatékonyabb célkódot eredményezhet.
Korai mérföldkövek a fordító technológia fejlesztésében:
1952 - Alick Glennie által a Manchesteri Egyetemen a Manchester Mark I számítógéphez kidolgozott Autokód-fordítót tekintik sokan az első fordítónak. 1952 - Grace Hopper Remington Rand csapata az A-0 programozási nyelv fordítóját írta (és már a fordító kifejezést használta annak leírására), bár az A-0 fordító inkább betöltőként vagy összekötőként működött, mintsem úgy mint egy teljes fordító. 1954-1957 - John Backus vezetésével az IBM fejlesztette ki a FORTRAN-t, amelyet általában az első magas szintű nyelvként tartanak számon. 1957-ben befejezték a FORTRAN fordítót, amelyet úgy tekintenek, mint az első egyértelműen teljes fordító bevezetését. 1959 - Az adatrendszer-nyelvi konferencia (CODASYL) elindította a COBOL fejlesztését. A COBOL kialakítása az A-0 és a FLOW-MATIC rajzokra támaszkodott. Az 1960-as évek elején a COBOL-t több architektúrára állították össze. 1958-1962 - John McCarthy, a Stanford Egyetemen tervezte meg a LISP-t. A szimbólumfeldolgozó képességek hasznos funkciókat nyújtottak a mesterséges intelligencia kutatására. 1962-ben a LISP 1.5 kiadás néhány eszközt felsorolt: Stephen Russell és Daniel J. Edwards írta az interpretert, míg Tim Hart és Mike Levin a fordítót és az assemblert írta.
A korai operációs rendszereket és szoftvereket assembly nyelven írták. A 60-as években és a 70-es évek elején az erőforrások korlátozottsága miatt a magas szintű nyelvek használata a rendszerprogramozásban továbbra is vitatott volt. Számos kutatási és ipari erőfeszítés azonban elindította az elmozdulást a magas szintű rendszerek programozási nyelvei felé, például a BCPL, a BLISS, a B és a C.
BCPL-t (alapvető kombinált programozási nyelv), amelyet 1966-ban tervezett Martin Richards a Cambridge-i Egyetemen, eredetileg fordító író eszközként fejlesztették ki. Számos fordítót implementáltak, Richards könyve betekintést nyújt a nyelvbe és annak fordítójára. A BCPL nemcsak befolyásos rendszerprogramozási nyelv volt, amelyet továbbra is használnak a kutatásban, hanem alapot adott a B és a C nyelv megtervezéséhez is.
A BLISS-t (alapvető nyelv a rendszerszoftverek megvalósításához) a Digital Equipment Corporation (DEC) PDP-10 számítógép számára fejlesztették ki W. A. Wulf Carnegie Mellon Egyetem (CMU) kutatócsoportja. A CMU csapata egy évvel később, 1970-ben fejlesztette ki a BLISS-11 fordítót.
A Multics (Multiplexed Information and Computing Service), idő-megosztó operációs rendszer projekt, bevonta az MIT-t, a Bell Labs-t, a General Electric-t (később Honeywell), és Fernando Corbató vezette az MIT-ből. A Multics az IBM és az IBM User Group által kifejlesztett PL / I nyelven készült. Az IBM célja az üzleti, tudományos és rendszerprogramozási követelmények teljesítése volt. Vannak más nyelvek is, amelyeket figyelembe lehetett volna venni, de a PL / én a legteljesebb megoldást kínálta, annak ellenére, hogy még nem implementálták.A Multics projekt első néhány évében a nyelv egy részét lefordították assembly nyelvre az Early PL / I (EPL) fordítóval, Doug McIlroy és Bob Morris segítségével, a Bell Labs-tól.Az EPL addig támogatta a projektet, amíg a teljes PL / I számára nem sikerült elindítani egy boot-pántozó fordítót.