쉘 스크립트를 사용하여 주어진 c/cpp 파일에서 함수 정의/내용을 추출하는 방법은 무엇입니까?

쉘 스크립트를 사용하여 주어진 c/cpp 파일에서 함수 정의/내용을 추출하는 방법은 무엇입니까?

머리를 긁적이며 다음과 같은 결과를 얻었습니다. 다음과 같은 .c 파일이 있다고 가정해 보겠습니다.

file.c
int fun1()
{
  int x = 3;
  return x;}
void f2()
{
   int x= 7; 
   int y =0;
}

함수 이름과 본문만 가져와서 다른 파일에 쓰는 방법을 알려줄 수 있는 사람이 있나요? ctags, grep 등을 시도했습니다. 함수 이름만 얻었고 본문은 얻지 못했습니다.

답변1

함수 이름과 본문만 가져와서 다른 파일에 쓰는 방법을 알려줄 수 있는 사람이 있나요? ctags, grep 등을 시도했습니다. 함수 이름만 얻었고 본문은 얻지 못했습니다.

구문을 실제로 이해해야 합니다. Grep 및 동료는 C 또는 C++를 구문 분석할 수 없습니다. awk 등과 마찬가지로 정규식 엔진이 구문 분석할 수 있는 언어 유형에 대한 수학적 설명이 있으며 C는 이 언어 범주에 속하지 않으며 C++는 C보다 구문 분석하기가 더 어렵습니다. ).

ctags순수 1990년대 초반 기술입니다(그 이후로 C 및 C++ 언어 버전으로 번역하면 오늘날 이 기술에 의존하는 것이 왜 의심스러운지 알 수 있습니다). 대부분의 파서 기반 "휴리스틱"은 실제로 C 또는 C++를 완전히 "이해"하기에는 너무 단순합니다. 그리고 눈치채셨듯이 아는 것에 신경쓰는 것도어디상징은 오히려콘텐츠어떤 기능. (나는 풍부한 ctag를 사용했는데, 마지막 버전은 2009였으므로 C++11++ 또는 C11++를 구문 분석하는 것은 불가능하지만 일반 ctag에 대해 더 나은 이야기를 들었지만 이것은 여전히 ​​컨텍스트가 없는 텍스트입니다. 다형성, 파일 간 템플릿 및 기본적으로 C++가 2003년 이후 중대형 프로젝트에 가져온 모든 기능을 처리하지 않는 기반 도구 정보입니다.

따라서 나쁜 소식은 기계어로의 실제 번역을 제외한 완전한 C 컴파일러(또는 전체 C++ 컴파일러)가 어느 정도 필요하다는 것입니다. 따라서 혼자서는 잘 작동하는 것을 작성할 수 없을 것입니다. 이렇게 복잡한 언어를 구현하기에는 팀이 너무 작습니다.

이것좋아요뉴스는 다른 사람이 그것을 발명했다는 것입니다일반적인도구(예: IDE, 린터, 구문 검사기 등)에 상당히 강력한 언어 파서에 대한 액세스를 제공하는 방법이며, 특히 C++의 경우 선택할 수 있는 것이 많습니다.
(저는 이 두 가지 매우 다른 언어를 생각하는데, C++가 더 어려운 언어이므로 C++ 지원이 놀랍습니다. 사실 C 구문은 C++의 하위 집합은 아니지만 C에서 C++의 나머지 빼기는 충분히 작습니다. C++를 사용할 수 있습니다. 실제로 ANSI 이전 C 스타일을 사용하려는 경우가 아니면 C 함수의 내용을 가져오는 파서입니다.

일부는언어 서버 프로토콜(LSP), 이것은 (neo)vim, emacs, Spyder, VSCode, Kate... 모든 "선언으로 이동", "오류 강조 표시", "인라인 정의 표시" 기능을 얻는 방법입니다.언어 서버LSP를 사용하여 보이는 내용을 이해합니다( clangdC++용 기본 LSP 서버).

당신도 똑같이 할 수 있습니다! LSP는 복잡한 프로토콜이 아닙니다. 실제로 이는 일련의 JSON-RPC 요청일 뿐입니다(JSON-RPC: "REST"라고 생각하지만 HTTP 대신 더 간단한 것을 사용하고 "일반적으로 무슨 일이 있어도" 대신 항상 JSON을 로드합니다). 따라서 JSON-RPC 명령줄 ​​클라이언트를 찾고, clangd스크립트에서 수동으로 시작한 다음 CLI 클라이언트를 사용하여 해당 클라이언트에 요청하거나(LSP 언어 사용), CLI 인터페이스가 있는 기존 클라이언트를 채택할 수 있습니다. 그리고 그것을 사용하십시오.

클라이언트의 복잡성을 확실히 좋아하지 않지만 LSP 서버의 복잡성을 C++(및 C)로 구문 분석해야 한다는 점을 고려하면 클라이언트 코드를 직접 작성하는 것만으로는 효율성을 크게 얻지 못할 것입니다. 그래서 저는 neovim이나 emacs를 백그라운드/데몬 모드로 밀어 넣고 해당 스크립팅 인터페이스(neovim: Lua, emacs: elisp)와 상호 작용합니다.

내기달리는 것만큼 쉬웠으면 좋겠지

cool_tool \
  -symbol-content "myns::containers::coolcont<Owlfeet>::hoot(int, int, std::string)" \
  -source-file owls.cc

그리고 hoot함수의 내용을 가져오지만 불행하게도 C++ 프로젝트에서는 기호가 어떻게 형성되는지, 어떤 오버로드가 어떤 파일에 구현되는지, 특정 함수 구현을 위한 후보가 무엇인지조차 알기 어렵습니다. 등을 포함한 모든 소프트웨어 모듈의 개요를 설명하는 컴파일 단위입니다. 따라서 컴파일 방법에 대한 지식을 가지고 사용하지 않으면 C++ 파서를 실패로 간주해야 합니다. 이것이 C++ LSP 도구가 일반적으로 IDE에 잘 통합되어 있고 여러 파일을 호출할 수 없는 이유입니다. 개별적으로 전화해서 죄송합니다. 이런 나쁜 소식을 전해드리게 되어 죄송합니다. clangd변경되지 않았거나 관련이 없더라도 포함된 모든 파일을 1000번 구문 분석할 필요 없이 clang 컴파일러의 언어 이해를 사용하여 내부적으로 많은 작업이 수행됩니다 .

상당히 얇고 가벼운 neovim을 "CLI 지원" IDE로 사용하면 모든 것이 잘 될 것입니다. 이것은 제가 추천할 수 있는 단일 명령줄 도구가 아닙니다.

일반적으로 C 및 C++ 소스 코드와 같은 복잡한 데이터로 작업하는 경우 셸 스크립트는 단순히 구축하려는 도구가 아닐 수도 있습니다. 매우 일반적인 언어를 다루는 글을 쓴다는 것은 매우 비일반적인 언어처럼 느껴집니다!

관련 정보