ANSI C의 Objective-C @encode () 컴파일러 지시문과 유사한 것을 어떻게 구현합니까?

StackOverflow https://stackoverflow.com/questions/2255637

문제

@encode 지시문은 const char *를 반환합니다. const char *는 전달 된 데이터 유형의 다양한 요소에 대한 코딩 된 유형 설명자입니다. 예제는 다음과 같습니다.

struct test
{ int ti ;
  char tc ;
} ;

printf( "%s", @encode(struct test) ) ;
// returns "{test=ic}"

크기가 ()를 사용하여 원시 유형을 결정하는 것을 볼 수있었습니다. 완전한 객체 인 경우 클래스 방법을 사용하여 내성을 수행 할 수 있습니다.

그러나 불투명 한 구조물의 각 요소를 어떻게 결정합니까?

도움이 되었습니까?

해결책

@lothars 답변은 "냉소적"일 수 있지만 불행히도 마크에 매우 가깝습니다. 같은 것을 구현하기 위해 @encode(), 유형 정보를 추출하려면 완전히 날려 버린 파서가 필요합니다. 글쎄, 적어도 "사소한"이외의 것은 @encode() 진술 (즉, @encode(char *)). 최신 컴파일러에는 일반적으로 2 ~ 3 개의 주요 구성 요소가 있습니다.

  • 프론트 엔드.
  • 중간 엔드 (일부 컴파일러의 경우).
  • 뒷머리.

프론트 엔드는 모든 소스 코드를 구문 분석하고 기본적으로 소스 코드 텍스트를 내부 "Machine Usable"양식으로 변환해야합니다.

백엔드는 내부 "Machine Useable"양식을 실행 가능한 코드로 변환합니다.

"중간 엔드"가있는 컴파일러는 일반적으로 일부 요구 때문에 그렇게합니다. 완전히 다른 언어로 구성된 다중 "프론트 엔드"를 지원합니다. 또 다른 이유는 최적화를 단순화하는 것입니다. 모든 최적화 패스는 동일한 중간 표현에서 작동합니다. 그만큼 gcc 컴파일러 스위트는 "3 단계"컴파일러의 예입니다. llvm "중간 및 백엔드"단계 컴파일러로 간주 될 수 있습니다. "낮은 레벨 가상 머신"은 중간 표현이며 모든 최적화는이 형식으로 이루어집니다. llvm 또한 마지막 두 번째 까지이 중간 표현에 보관할 수 있습니다. 이것은 "링크 시간 최적화"를 허용합니다. 그만큼 clang 컴파일러는 실제로 (효과적으로) 출력하는 "프론트 엔드"입니다. llvm 중간 표현.

따라서 추가하고 싶다면 @encode() '기존'컴파일러에 대한 기능은 아마도 "소스 소스" '컴파일러 / 사전 처리기'로 수행해야 할 것입니다. 이것이 원래 대상 C 및 C ++ 컴파일러가 작성된 방식이었습니다. 입력 소스 텍스트를 구문 분석하여 "Plain C"로 변환 한 다음 표준 C 컴파일러로 공급되었습니다. 이를 수행하는 몇 가지 방법이 있습니다.

직접 굴립니다

  • 사용 yacc 그리고 lex ANSI-C 파서를 모으기 위해. 문법이 필요합니다. Ansi C 문법 (YACC) 좋은 시작입니다. 사실, 내가 말할 때 분명합니다 yacc, 나는 정말로 의미한다 바이슨 그리고 flex. 또한 느슨하게, 다른 다양한 yacc 그리고 lex C 기반 도구와 마찬가지로 : 레몬, DPARSER, 등...
  • 사용 perl ~와 함께 얍형 제본 또는 Eyapp, pseudo-yacc 클론 perl. C 기반에 비해 아이디어를 신속하게 프로토 타이핑하는 데 더 나은 yacc 그리고 lex- 그것의 perl 결국 : 정규 표현식, 연관 배열, 메모리 관리 없음 등
  • 파서를 구축하십시오 antlr. 이 도구 체인에 대한 경험은 없지만 Java 개발자에게 더 많은 장비를 제공하는 또 다른 "컴파일러 컴파일러"도구입니다. 무료로 사용 가능한 C 및 Objective-C 문법이있는 것으로 보입니다.

다른 도구를 해킹하십시오

메모: 나는 이러한 도구를 사용하여 추가하는 것과 같은 일을하는 개인적인 경험이 없습니다. @encode(), 그러나 나는 그들이 큰 도움이 될 것이라고 생각합니다.

  • -이 도구에 대한 개인적인 경험은 없지만 C 소스 코드를 구문 분석 한 다음 "작업"을 위해 설계되었습니다. 문서에서 수집 할 수있는 것에서이 도구를 사용하면 필요한 유형 정보를 추출 할 수 있습니다.
  • 부족한 - 볼 가치가 있지만 확실하지 않습니다.
  • 그 소리 -이 목적으로 그것을 사용하지는 않았지만 목표 중 하나는 이런 종류의 물건에 대해 "쉽게 해킹 할 수있는"목표를 달성하는 것이 었습니다. 특히 모든 구문 분석의 "무거운 리프팅"을 수행하는 데있어서 (개인적인 경험이 없음) "흥미로운"부분에 집중할 수있게 해주 며,이 경우 컨텍스트와 구문 민감한 유형 정보를 추출한 다음이를 변환 할 수 있습니다. 일반 C 문자열에.
  • GCC 플러그인 - 플러그인은 GCC 4.5 (컴파일러의 현재 알파/베타 버전) 기능이며 "클릭 자에 쉽게 연결하여"필요한 유형 정보를 추출 할 수 있습니다. 플러그인 아키텍처가 이런 종류의 일을 허용하는지 전혀 모릅니다.

기타

  • Coccinelle - 최근에 "나중에 보아라"를 북마크했습니다. 이 "" "가 원하는대로 할 수 있으며" "많은 노력으로" "할 수 있습니다.
  • 메타 - 최근에도 북마크했습니다. 이것이 얼마나 유용한 지 모르겠습니다.
  • MyGCC - "아마도"당신이 원하는 것을 할 수 있습니다. 흥미로운 아이디어이지만 원하는 것에 직접적으로 적용 할 수는 없습니다. 웹 페이지에서 : "MyGCC를 사용하면 프로그래머는 구문, 제어 흐름 및 데이터 흐름 정보를 고려하여 자체 점검을 추가 할 수 있습니다."

연결.

#1, 보너스 링크를 편집합니다.

@Lothar는 그의 의견에서 좋은 지적을합니다. 나는 실제로 포함하려고했다 lcc, 그러나 길을 따라 길을 잃은 것 같습니다.

  • LCC - lcc C 컴파일러. 이것은 적어도 소스 코드 크기 측면에서 특히 작은 C 컴파일러입니다. 또한 책이 있습니다, 내가 강력히 추천합니다.
  • TCC - tcc C 컴파일러. 교육학 만큼은 아닙니다 lcc, 그러나 여전히 볼 가치가 있습니다.
  • POC - poc 목표 C 컴파일러. 이것은 "소스 소스"객관적인 C 컴파일러입니다. 객체 C 소스 코드를 구문 분석하고 C 소스 코드를 방출 한 다음 전달됩니다. gcc (음, 보통 gcc). 사용할 수없는 많은 객관적인 C 확장 / 기능이 있습니다. gcc. 확실히 볼 가치가 있습니다.

다른 팁

ANSI C 컴파일러를 먼저 구현하여이를 구현 한 다음 구현 특정 pragmas 및 기능을 추가합니다.

예, 나는 이것이 냉소적 인 대답이라는 것을 알고 있으며 다운 보트를 받아들입니다.

이를 수행하는 한 가지 방법 @encode... 해당 문자열 문자가 있습니다.

다른 접근법은 프로그램이 컴파일 된 경우 -g, 런타임에 프로그램의 디버그 정보에서 유형 정의를 읽거나 사용하는 함수를 작성하는 것입니다. gdb 또는 당신을 위해 그것을 읽은 다음 원하는대로 그것을 재구성하는 다른 프로그램. 그만큼 gdb ptype 명령을 사용하여 특정 유형의 정의를 인쇄 할 수 있습니다 (또는 불충분 한 경우 maint print type, 이것은 원하는 것보다 훨씬 더 많은 정보를 인쇄 할 것입니다).

지원하는 컴파일러를 사용하는 경우 플러그인 (예 : GCC 4.5),이를 위해 컴파일러 플러그인을 작성할 수도 있습니다. 그런 다음 플러그인이 컴파일러가 이미 구문 분석 한 유형 정보를 활용할 수 있습니다. 분명히이 접근법은 매우 컴파일러 별 일 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top