Отговорът на @Lothars може да е „циничен“, но за съжаление е доста близо до целта. За да приложите нещо като @encode()
, имате нужда от пълен анализатор, за да извлечете информацията за типа. Е, поне за нещо различно от "тривиални" @encode()
твърдения (т.е. @encode(char *)
). Съвременните компилатори обикновено имат два или три основни компонента:
- Предният край.
- Междинният край (за някои компилатори).
- Задният край.
Предният край трябва да анализира целия изходен код и основно преобразува текста на изходния код във вътрешна, „машинно използваема“ форма.
Задната част превежда вътрешната, „използваема от машината“ форма в изпълним код.
Компилаторите, които имат "междинен край", обикновено го правят поради някаква нужда: те поддържат множество "предни части", вероятно съставени от напълно различни езици. Друга причина е да се опрости оптимизацията: всички пасове за оптимизация работят върху едно и също междинно представяне. Компилаторният пакет gcc
е пример за "тристепенен" компилатор. llvm
може да се счита за компилатор на етап "междинен и заден край": "Виртуалната машина от ниско ниво" е междинното представяне и цялата оптимизация се извършва в тази форма. llvm
също може да го запази в това междинно представяне до последната секунда - това позволява "оптимизиране на времето за връзка". Компилаторът clang
наистина е "преден край", който (ефективно) извежда llvm
междинно представяне.
Така че, ако искате да добавите @encode()
функционалност към „съществуващ“ компилатор, вероятно ще трябва да го направите като „компилатор/препроцесор“ от „източник към източник“. Това беше начинът, по който бяха написани оригиналните компилатори на Objective-C и C++ - те анализираха входния изходен текст и го преобразуваха в "обикновен C", който след това беше въведен в стандартния C компилатор. Има няколко начина да направите това:
Навийте своя собствена
- Използвайте
yacc
и lex
, за да съставите анализатор на ANSI-C. Ще ви е необходима граматика - ANSI C граматика (Yacc) е добро начало. Всъщност, за да бъде ясно, когато казвам yacc
, наистина имам предвид bison и flex
. И също така, свободно, другите различни yacc
и lex
подобни на C-базирани инструменти: lemon, dparser и др...
- Използвайте
perl
с Yapp или EYapp, които са псевдо-yacc
клонинги в perl
. Вероятно по-добре за бързо прототипиране на идея в сравнение с базираните на C yacc
и lex
- все пак е perl
: регулярни изрази, асоциативни масиви, без управление на паметта и т.н.
- Създайте своя анализатор с Antlr. Нямам опит с тази верига от инструменти, но това е друг инструмент за „компилиращ компилатор“, който (изглежда) е насочен повече към разработчиците на Java. Изглежда, че има свободно достъпни C и Objective-C граматики.
Хакнете друг инструмент
Забележка: Нямам личен опит с използването на който и да е от тези инструменти, за да направя нещо като добавяне на @encode()
, но подозирам, че биха били голяма помощ.
- CIL – Нямам личен опит с този инструмент, но е предназначен за анализиране на изходния код на C и след това „правене неща" с него. От това, което мога да намеря от документите, този инструмент трябва да ви позволи да извлечете информацията за типа, от която се нуждаете.
- Sparse – Струва си да се разгледа, но не съм сигурен.
- clang – Не съм го използвал за тази цел, но се твърди, че една от целите е била да го направя „лесно хакващ "само за такива неща. По-специално (и отново, без личен опит) в извършването на "тежката работа" на цялото анализиране, което ви позволява да се концентрирате върху "интересната" част, която в този случай би била извличане на чувствителна към контекста и синтаксиса информация за типа и след това да я преобразувате в към обикновен C низ.
- gcc плъгини – плъгините са gcc 4.5 (което е текущата алфа/ бета версия на компилатора) и „може“ да ви позволи лесно да се свържете с компилатора, за да извлечете информацията за типа, от която се нуждаете. Нямам представа дали архитектурата на плъгина позволява подобни неща.
други
- Coccinelle – Маркирахте това наскоро, за да „разгледате по-късно“. Това „може“ да е в състояние да направи това, което искате, и „може“ да е в състояние да го направи с много усилия.
- MetaC – Маркирах и този наскоро. Нямам представа колко полезно би било това.
- mygcc - „Може“ да направи това, което искате. Това е интересна идея, но не е пряко приложима към това, което искате. От уеб страницата: "Mygcc позволява на програмистите да добавят свои собствени проверки, които вземат предвид синтаксиса, контролния поток и информацията за потока от данни."
Връзки.
Редактиране #1, бонус връзките.
@Lothar прави добра точка в коментара си. Всъщност възнамерявах да включа lcc
, но изглежда, че се е загубил по пътя.
- lcc –
lcc
C компилаторът. Това е C компилатор, който е особено малък, поне по отношение на размера на изходния код. Освен това има книга, която силно препоръчвам.
- tcc – Компилаторът
tcc
C. Не е толкова педагогически като lcc
, но определено все пак си заслужава да бъде разгледан.
- poc – Компилаторът
poc
Objective-C. Това е Objective-C компилатор от източник към източник. Той анализира изходния код на Objective-C и излъчва изходния код на C, който след това предава на gcc
(е, обикновено gcc
). Има редица разширения/функции на Objective-C, които не са налични в gcc
. Определено си заслужава да се разгледа.
person
johne
schedule
14.02.2010