C 전처리기 교체
저는 제 C와 Objective-C 소스 코드를 전처리하기 위해 C 프리프로세서가 아닌 다른 것을 사용하는 것에 관심이 있습니다.좋은 대안이 있습니까?
예를 들어 C 코드 중간에 파이썬 또는 펄 스니펫으로 탈출할 수 있는 것과 스니펫이 C를 뱉어낸 다음 정상적으로 컴파일되는 것이 있습니다.
PHP를 C 전처리기로 사용할 수 있습니다.이점은 다음과 같습니다.
- 매우 유사한 구문이므로 구문 강조 표시가 작동합니다.
<?
그리고.?>
표준 C에서는 사용되지 않습니다(비표준 C에서는 최소/최대 값을 반환하는 오래된 GCC 확장 연산자만 손상됩니다).- 도서관이 풍부합니다.
- 튜링 완료입니다.
- 매크로의 사용은 매우 명시적입니다.(스니크 C 프리프로세서 매크로와 비교)
하지만 진지한 사용을 위해서는 사전 처리된 코드를 디버깅하기 위해 PHP가 #line 디렉티브를 인쇄하도록 해야 합니다.
<?php include_once "stdio.h"; ?>
int main()
{
<?php
for($i = 0; $i < 20; $i++)
echo 'printf("%d\n", '.$i.');';
?>
}
Cog는 정확히 사전 처리기는 아니지만 코드에 인라인으로 연결되어 즉시 무언가를 생성합니다.
m4.m4를 하는 것이 입니다.
http://www.gnu.org//m4/http://www.gnu.org/software/m4/
코드를 실행하고 그 결과를 연결하는 아이디어를 준인용이라고 합니다.실행하는 코드가 오래된 코드입니다.
저는 Lua를 사용하여 이 문제를 해결하는 방법을 알고 있습니다.사용한 적이 있습니다.string.gsub
제가 직접 작성한 안티오테이션 기능이 있습니다.저는 반인용 부호에 셸 구문을 사용했습니다.셸에서와 같이 앤티포팅된 코드는 문자열을 반환한 다음 코드로 스플라이스됩니다.
아래prog
가 있는 C이며, 인용부있는 C 드입니다코입니다.antiquote
반표법 함수입니다.나는 루아의 특별한 문자열을 사용하여 이중 대괄호를 인용하여 최대한 활용했습니다.실제로 당신은 이것을 하지 않을 것입니다; 당신은.prog
별열로
names = { 'John', 'Paul', 'George', 'Ringo' }
local prog = [===[
#include <stdio.h>
main() {
$(local out = { }
for _, n in ipairs(names) do
table.insert(out, string.format([[ printf("The name is %%s\n", %q);]], n))
end
return table.concat(out, '\n ')
)
}
]===]
local function antiquote(s)
local body = s:match '^%$%((.*)%)$'
return assert(loadstring(body))()
end
prog = prog:gsub('%$%b()', antiquote)
io.stdout:write(prog)
사용 중인 프로그램은 다음과 같습니다.
: nr@curlycoat 1181 ; lua /home/nr/tmp/emit-c.lua
#include <stdio.h>
main() {
printf("The name is %s\n", "John");
printf("The name is %s\n", "Paul");
printf("The name is %s\n", "George");
printf("The name is %s\n", "Ringo");
}
물론, 표준 C 전처리기는 매우 제한적입니다.
저는 최근에 그런 도구를 만들었습니다: https://github.com/d-ash/perlpp
예를 들어 이것은
<?
my @types = ('char', 'int', 'long');
foreach (@types) {
?>
<?= $_ ?> read_<?= uc($_) ?>(<?= $_ ?>* v);
<? } ?>
이것이 됩니다.
char read_CHAR(char* v);
int read_INT(int* v);
long read_LONG(long* v);
구문은 PHP와 비슷하지만 Perl을 대신 사용하며 텍스트를 Perl 문자열로 캡처할 수 있습니다.
cxw에 의한 편집 — @d-ash의 승인으로 저는 perlpp의 관리자이기도 합니다.질문이 있으시면 언제든지 저에게 편지를 주세요!
문제를 조금 추상화하면 코드에 대한 템플릿 엔진을 찾는 것입니다.대부분의 웹 사이트가 동적으로 생성된 콘텐츠를 정적 템플릿에 삽입하는 것처럼 동적으로 생성된 코드를 프로그램에 삽입하려고 합니다.
저는 현재 대부분의 템플릿 작업에 Jinja2(Python)를 사용하고 있습니다. 저는 그것이 모든 면에서 매우 구성 가능하다는 것을 알았습니다.
만약 여러분이 C++로 손을 더럽힐 준비가 되어 있다면, Boost에는 Spirit 재귀 하강 파서를 사용하여 만들어진 Wave 파서가 있습니다.이것은 C와 C++의 모든 최신 사양을 준수하는 완전한 C 전처리기입니다(그리고, 확장적으로, 목표 C, AFAICS).
모듈식성이 뛰어나 추가 작업을 수행할 수 있는 드라이버를 직접 전환할 수 있습니다.
http://www.boost.org/libs/wave/doc/introduction.html
저는 과거에 이 같은 문제에 대해 생각해 본 적이 있습니다.코드를 컴파일하려는 사람은 누구나 새로운 전처리 도구가 필요하기 때문에 문제가 없는지 확인하십시오.사용자만 작업할 경우 문제가 없지만 다른 사용자가 코드를 사용할 수 있도록 하려면 도구 요구 사항을 추가하는 것이 좋은지 여부를 고려해야 합니다.
짧은 대답은 "아니오"입니다.전처리기는 C의 의미론과 매우 밀접하게 연결되어 있어서 실제로 제거할 수 없으며, 일부 컴파일러는 예전처럼 별도의 단계도 아닙니다. Mac에서 목표 C를 컴파일하는 것은 목표 C 구문을 구문 분석합니다.따라서 C에 소스 텍스트를 전달하기 전에 m4와 같은 다른 매크로 프로세서를 사용하여 소스 텍스트를 처리할 수는 있지만, C 전처리기를 제거하는 것이 아니라 전처리의 다른 단계를 추가하는 것입니다.
하지만 여기에는 더 깊은 질문이 있습니다. CPP 단계를 제거하여 무엇을 얻고 싶습니까?
CPP는 C 코드에 대해 아마도 다시 구현할 필요가 없는 많은 중요한 작업을 수행합니다.대신 당신이 찾고 있는 것처럼 보이는 것은 C 코드를 방출하는 템플릿 프로세스일 수 있습니다.
Cheetah는 당신이 파이썬을 사용할 수 있게 해주는 많은 것들 중 하나입니다.Python을 사용하는 다른 언어들도 있지만, Cheetah는 출력에 구애받지 않는 것으로 유명하며, 일부 템플릿 엔진은 HTML/XML에 매우 중점을 두고 있습니다.조사해 보세요.
즐겨찾는 프로그래밍 언어를 사용하여 소스 파일(.c/.cpp 또는 .h 등)을 생성하는 스크립트/도구를 작성할 수 있습니다.간단히#include
또는 프로젝트로 컴파일할 수 있습니다.근처에 댓글을 달면 도움이 될 수 있습니다.#include
도구가 무엇인지/어디서 무엇이 생성되는지 식별합니다.
이것은 "실제" 전처리기를 사용하는 것만큼 편리하지 않을 수도 있지만 작동할 것입니다.한편, 그것은 정말로 당신의 경우에 달려있습니다.
저는 2001년에 파이썬과 유사한 사전 분석 http://ray.cg.tuwien.ac.at/rft/Papers/PYM/pym.html 을 소개한 논문을 보았습니다.누가 사용하고 있는지 확실하지 않습니다.
저는 사람들이 무엇을 생각해내는지 보고 싶습니다.저는 Perl로 작성된 전처리기로 작은 사용자 지정 작업을 수행하는 경향이 있습니다.프리프로세서를 호출하는 Make 파일을 쉽게 설치할 수 있습니다.예를 들어 'meta'라는 프로그램을 호출하여 'file.c.meta'에서 'file.c'를 생성하는 규칙이 있습니다.
% :: %.meta
meta $< > $@
저는 커스텀 핏 C 데이터 구조를 생성하는 것과 같은 '메타'로 재미있는 일을 하고 있습니다.그것은 분명히 제가 탐험할 것을 제안하는 방향입니다.저의 희망은 결국 C++ 템플릿과 대략 평행한 메타 라이브러리를 생각해 내는 것입니다.
언급URL : https://stackoverflow.com/questions/396644/replacements-for-the-c-preprocessor
'programing' 카테고리의 다른 글
C의 함수에서 로컬 변수 반환 (0) | 2023.06.10 |
---|---|
스크킷 학습 의사 결정 트리에서 의사 결정 규칙을 추출하는 방법은 무엇입니까? (0) | 2023.06.10 |
Oracle varchar2의 문자열 16진수 값을 표시하시겠습니까? (0) | 2023.06.10 |
입력 텍스트 상자에서 값 가져오기 (0) | 2023.05.31 |
Rspec에서 특정 테스트만 실행하려면 어떻게 해야 합니까? (0) | 2023.05.31 |