Использование препроцессора C для языков, отличных от C
В записи Википедии для C Preprocessor указано:
Язык препроцессора директивы являются агностическими для грамматики C, поэтому препроцессор C также может использоваться независимо для обработки других типы файлов.
Как это можно сделать? Любые примеры или методы?
EDIT: Да, меня больше всего интересует обработка макросов. Несмотря на то, что это, вероятно, нецелесообразно или не поддерживается, было бы полезно узнать, что возможно.
Ответы
Ответ 1
Вы можете напрямую вызвать CPP:
cpp <file>
Вместо того, чтобы называть его gcc:
gcc -E filename
Помните, однако, что, как упоминалось в той же статье в Википедии, язык препроцессора C на самом деле не оборудован для общего использования:
Однако, поскольку препроцессор C не имеет функций какого-либо другого препроцессоры, такие как рекурсивные макросы, выборочное расширение согласно для цитирования, оценки строк в условных выражениях и Turing полнота, она очень ограничена по сравнению с более общим макросом процессор, такой как m4.
Считаете ли вы, что занимаетесь более гибким языком обработки макросов, например, упомянутым выше m4?
Ответ 2
Многие компиляторы C имеют флаг, который сообщает им только предварительную обработку. С gcc это флаг -E. например:
$ gcc -E -
#define FOO foo
bar FOO baz
выведет:
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "<stdin>"
bar foo baz
С другими компиляторами C вам нужно будет проверить руководства, чтобы посмотреть, как использовать swithc только в режиме предварительной обработки.
Ответ 3
Например, Ассемблер. Хотя многие ассемблеры имеют свой собственный путь к #include headers и макросам #define, для этого может быть полезно использовать препроцессор C. Например, у GNU есть неявные правила для превращения файлов *.S в файлы *.s, запустив препроцессор ('cpp'), прежде чем подавать файл *.s на ассемблер GNU ('as').
Ответ 4
Да, это можно сделать, проанализировав собственный язык через препроцессор gcc (например, "gcc -E" ).
Мы сделали это на моей работе с нашим нашим, конкретным языком. Это имеет ряд преимуществ:
- Вы можете использовать операторы C include (#include), которые очень мощные
- Вы можете использовать свои конструкции #ifdef
- Вы можете определить константы (#define MAGIC_NUMBER 42) или макрофункции (#define min (x, y) ((x (< (y)? (x): (y))
... и другие вещи в процессоре c.
ОДНАКО, вы также наследуете небезопасные конструкции C, и препроцессор, не интегрированный с вашим основным языком, является причиной этого. Подумайте о минимальном макросе и сделайте что-то вроде:
a = 2;
b = 3;
c = min(a--, b--);
Подумайте, какое значение a и b будут иметь после функции min?
То же самое верно в отношении не типизированных констант, которые вы вводите
Подробнее см. в Safer C.
Ответ 5
Обычно вы можете вызывать компилятор C с возможностью только для предварительной обработки (и игнорировать любые #line-инструкции). Возьмем это как простой пример:
<?php
function foo()
{
#ifdef DEBUG
echo "Some debug info.";
#endif
echo "Foo!";
}
foo();
Мы определяем исходный файл PHP с инструкциями препроцесса. Затем мы можем обработать его (gcc также может это сделать):
cl -nologo -EP foo.php > foo2.php
Так как DEBUG
не определено, первая echo
лишается. Плюс вот, что строки, начинающиеся С#, являются комментариями в PHP, поэтому вам не нужно предварительно обрабатывать их для сборки "debug".
Изменить: поскольку вы спрашивали о макросах. Это отлично работает и может быть использовано для создания кода шаблона и т.д.
Ответ 6
Используя компилятор Microsoft, я думаю (я просто посмотрел, не протестировал его), что он /P компилятор.
У других компиляторов, вероятно, есть похожие варианты (или для некоторых компиляторов препроцессор может быть другим исполняемым файлом, который обычно выполняется неявным образом компилятором, но который вы также можете запускать явно отдельно).
Ответ 7
Предполагая, что вы используете GCC, вы можете взять любой простой старый текстовый файл, независимо от его содержимого, и запустить:
gcc -E filename
Любые препроцессорные директивы в файле будут обрабатываться препроцессором, и GCC затем выйдет.
Дело в том, что неважно, каков фактический контент текстового файла, так как все препроцессор заботится о его собственных директивах.
Ответ 8
Я слышал о людях, использующих предварительный процессор C в коде Ada. У Ada нет препроцессора, поэтому вам нужно сделать что-то подобное, если вы хотите препроцитировать свой код.
Однако это было убедительное дизайнерское решение, чтобы не дать его одному, так что это очень не-Ада. Я бы не предложил, чтобы кто-нибудь это делал.
Ответ 9
Некоторое время назад я немного поработал над проектом, который использовал imake
для генерации make файла. Насколько я помню, в основном синтаксис препроцессора c генерировал файлы make.
Ответ 10
Препроцессор C также может быть вызван Glasgow Haskell Compiler (GHC) перед компиляцией кода Haskell, передав -cpp
.
Ответ 11
Вы можете реализовать препроцессор C в компиляторе для другого языка.
Вы можете использовать его для препроцесса любого текстового файла, но для этой цели есть намного лучше.
Ответ 12
В основном, это говорит о том, что препроцессоры не имеют никакого отношения к синтаксису Си. Они в основном простые парсеры, которые следуют набору правил. Таким образом, вы можете использовать препроцессоры, как если бы вы использовали sed или awk для некоторых глупых задач. Не спрашивайте меня, почему вы когда-нибудь захотите это сделать.
Например, в текстовом файле:
#define pi 3.141
pi is not an irrational number.
Затем вы запустите препроцессор, и вы получите.
3.141 не является иррациональным числом.