2009-09-18 37 views
40

Google không bật lên bất kỳ thứ gì có vẻ liên quan.Có một thư viện Python tốt có thể phân tích cú pháp C++ không?

tôi có một loạt các hiện, làm việc C++, và tôi muốn sử dụng python để thu thập thông qua nó và tìm ra mối quan hệ giữa lớp học, vv

EDIT: Chỉ cần muốn chỉ ra: Tôi don Tôi nghĩ rằng tôi cần hoặc muốn phân tích từng bit của C++; Tôi chỉ cần một cái gì đó đủ thông minh để nhận trên lớp, chức năng và khai báo biến thành viên, và để bỏ qua các định nghĩa chức năng.

+0

Bạn không thể làm điều này nếu không có trình phân tích cú pháp C++ đầy đủ. –

+1

Nếu bạn không hài lòng với việc không bắt được các trường hợp cạnh 0,1%, bạn có thể thoát khỏi phân tích cú pháp regex. Tôi khá chắc chắn có rất nhiều trình soạn thảo văn bản làm điều này để làm nổi bật cú pháp/phân tích cú pháp của chúng. Ví dụ, Sublime Text đi kèm với các tệp phân tích cú pháp regex cho một loạt các ngôn ngữ bao gồm C++ (xem C++. TmLanguage). –

Trả lời

29

C++ nổi tiếng là khó phân tích cú pháp. Hầu hết những người cố gắng làm điều này đúng cách kết thúc việc tách rời một trình biên dịch. Trong thực tế, đây là (một phần) tại sao LLVM bắt đầu: Apple cần một cách họ có thể phân tích cú pháp C++ để sử dụng trong XCode phù hợp với cách trình biên dịch phân tích nó.

Đó là lý do tại sao có các dự án như GCC_XML mà bạn có thể kết hợp với thư viện xml python.

Một số dự án không trình biên dịch mà dường như làm một công việc khá tốt ở phân tích cú pháp C++ là:

  • Eclipse CDT
  • OpenGrok
  • Doxygen
+2

+1 - gcc-xml là cách để đi, trừ khi bạn muốn một giải pháp có trả tiền (và đắt tiền) như lối vào EDG. –

+5

Lưu ý rằng gcc-xml không phân tích cú pháp mọi thứ. Cụ thể, các phần tử chức năng không được phân tích cú pháp. – liori

1

This page hiển thị ngữ pháp C++ được viết bằng Antlr và bạn can generate Python code từ đó.

Dường như có ai đó đang làm việc trên trình phân tích cú pháp C++ trong pyparsing, nhưng tôi không thể tìm ra trạng thái hiện tại hoặc trạng thái của nó.

+2

Không thể có ngữ pháp C++ hoạt động đầy đủ trong ANTLR, hoặc, thực sự, hầu như bất kỳ ngôn ngữ mô tả ngữ pháp nào khác. Ngữ pháp C++ không phải là ngữ cảnh. Do những thứ như lập trình meta mẫu, việc phân tích cú pháp C++ có hiệu quả đòi hỏi phải viết một trình thông dịch của một ngôn ngữ hoàn chỉnh Turing chỉ để có thể phân biệt các khai báo biến từ các biểu thức. –

+0

@Pavel: Bạn có thể có trình phân tích cú pháp C++ hoàn hảo bằng cách sử dụng các quy tắc ngữ pháp không có ngữ cảnh, nếu bạn có một trình phân tích cú pháp phong nha. Bạn không phải giải quyết tên và loại trong quá trình phân tích cú pháp; xem câu trả lời Bộ công cụ DMS để có trình phân tích cú pháp C++ đầy đủ thực hiện chính xác những gì bạn nói không thể thực hiện được. –

+1

@Ira: trong một số ngữ cảnh, nếu bạn không giải quyết loại này, bạn không biết điều gì đó là gì. Ví dụ, hãy xem xét: 'a :: b d', trong đó' a' là một mẫu lớp khác với các chuyên ngành, một trong số đó định nghĩa 'b' là một mẫu lớp khác và thứ hai định nghĩa' b' là thành viên enum. Tùy thuộc vào chuyên môn nào được chọn (tức là về kích thước 'int'), toàn bộ điều hoặc là khai báo biến' d': 'a :: b d' - hoặc nó là một biểu thức:' a :: b < c > d'. Vì vậy, bây giờ chúng tôi đã hoàn toàn tuân thủ mã ISO C++, đó là al để thực hiện phụ thuộc. –

1

Không có thư viện tốt (miễn phí) nào để phân tích cú pháp C++ ở bất kỳ ngôn ngữ nào.
Lựa chọn tốt nhất của bạn có thể là Dehydra plugin g ++, clang hoặc Elsa.

5

Bạn sẽ không tìm thấy một thả thư viện Python để làm điều này. Phân tích cú pháp C++ là khó, và một vài trình phân tích cú pháp đã được viết mà không phải là một phần của trình biên dịch. Bạn có thể tìm thấy tóm tắt tốt về các vấn đề here.

Đặt cược tốt nhất có thể là clang, vì hỗ trợ C++ là well-established. Mặc dù đây không phải là một giải pháp Python, nó có vẻ như là nó sẽ được sử dụng lại trong một trình bao bọc Python, với sự nhấn mạnh về đóng gói và thiết kế tốt trong sự phát triển của nó.

+2

Khó sử dụng? Hết sức. –

4

Nếu bạn đã định dạng nhận xét của mình theo cách tương thích, Doxygen sẽ thực hiện một công việc tuyệt vời. Nó thậm chí sẽ vẽ sơ đồ thừa kế nếu bạn đã cài đặt graphviz.

Ví dụ, chạy Doxygen trên như sau:

/// <summary> 
/// A summary of my class 
/// </summary> 
public class MyClass 
{ 
protected: 
    int m_numOfWidgets; /// Keeps track of the number of widgets stored 

public: 
    /// <summary> 
    /// Constructor for the class. 
    /// </summary> 
    /// <param paramName="numOfWidgets">Specifies how many widgets to start with</param> 
    MyClass(int numOfWidgets) 
    { 
     m_numOfWidgets = numOfWidgets; 
    } 

    /// <summary> 
    /// Increments the number of widgets stored by the amount supplied. 
    /// </summary> 
    /// <param paramName="numOfWidgets">Specifies how many widgets to start with</param> 
    /// <returns>The number of widgets stored</returns> 
    IncreaseWidgets(int numOfWidgetsToAdd) 
    { 
     m_numOfWidgets += numOfWidgets; 
     return m_numOfWidgets; 
    } 
}; 

sẽ biến tất cả những ý kiến ​​vào các mục trong file .html. Với các thiết kế phức tạp hơn, kết quả thậm chí còn có lợi hơn - thường dễ dàng hơn nhiều so với việc cố gắng duyệt qua nguồn.

+0

Doxygen là một phần mềm tuyệt vời cho các chương trình C++! Sử dụng nó trên một chương trình người khác đã viết và nó làm cho nó dễ dàng hơn nhiều để tìm ra những gì đang xảy ra ở đâu. – corymathews

0

wiki pyparsing cho thấy ví dụ này - tất cả những gì nó làm là phân tích cấu trúc phân tích cú pháp, do đó, điều này có thể cung cấp cho bạn một cái nhìn thoáng qua về độ lớn của vấn đề.

Tôi đề nghị bạn (hoặc thậm chí tốt hơn, chủ lao động của bạn) bỏ ra $ 200 và mua Enterprise Architect from sparxsystems. Phần mềm này là đáng kinh ngạc mạnh mẽ cho giá cả, và bao gồm các tính năng kỹ thuật đảo ngược mã khá tốt. Bạn sẽ chi tiêu nhiều hơn thế này trong thời gian của riêng bạn để chỉ nhận được khoảng 2% công việc làm. Trong trường hợp này, "mua" thắng hơn "làm".

0

Ctypes sử dụng gcc-xml để tạo mã. Có thể là cpptypes cũng vậy. Thậm chí nếu không, bạn có thể sử dụng gcc-xml để tạo XML từ tệp C++ của bạn, sau đó phân tích cú pháp xml bằng một trong các trình phân tích cú pháp XML XML bên trong hoặc bên thứ ba.

43

Không phải là câu trả lời như vậy, nhưng chỉ để chứng minh cách phân tích cú pháp C++ thực sự là đúng. Bản trình diễn yêu thích của tôi:

template<bool> struct a_t; 

template<> struct a_t<true> { 
    template<int> struct b {}; 
}; 

template<> struct a_t<false> { 
    enum { b }; 
}; 

typedef a_t<sizeof(void*)==sizeof(int)> a; 

enum { c, d }; 
int main() { 
    a::b<c>d; // declaration or expression? 
} 

Điều này hoàn toàn hợp lệ, chuẩn C++, nhưng ý nghĩa chính xác của dòng nhận xét tùy thuộc vào việc triển khai của bạn. Nếu sizeof(void*)==sizeof(int) (điển hình trên nền tảng 32 bit), đó là khai báo biến cục bộ d loại a::b<c>. Nếu điều kiện không giữ, thì đó là biểu thức no-op ((a::b < c) > d). Việc thêm một hàm tạo cho a::b sẽ thực sự cho phép bạn phơi bày sự khác biệt thông qua sự hiện diện/vắng mặt của các tác dụng phụ.

+3

Cái ác, vâng, nhưng có thể phân tích được. Tôi đã cập nhật this SO answer với một phân tích cú pháp của mã này: –

+3

C++: khó khăn cho con người, khó khăn hơn cho máy tính. – Dave

4

Pycparser là một phân tích cú pháp đầy đủ và chức năng cho ANSI C. lẽ bạn có thể mở rộng nó để C++ :-)

+1

"Có lẽ bạn có thể mở rộng nó đến c + +" và chỉ có bao nhiêu công việc sẽ được? –

+3

@KevinKostlan: Quá nhiều, do đó là mặt cười ... Tôi không thể thành thật đề xuất lộ trình hành động này hôm nay. Tôi muốn sử dụng Clang bindings để thay thế. –

+0

@EliBendersky Tôi thấy bài viết này hữu ích (http://eli.thegreenplace.net/2011/07/03/parsing-c-in-python-with-clang);) – Klik

0

Dưới đây là một dự án SourceForge rằng tuyên bố để phân tích C++ tiêu đề. Như những người bình luận khác đã chỉ ra, không có giải pháp chung, nhưng bạn có vẻ như nó sẽ làm đủ cho nhu cầu của bạn. (Tôi chỉ cần chạy qua nó cho một nhu cầu tương tự và đã không thử nó bản thân mình được nêu ra.)

http://sourceforge.net/projects/cppheaderparser/

0

Dự án Clang cung cấp thư viện cho chỉ phân tích cú pháp C++.

Hoặc với Clang và GCC bạn có thể tạo ra một đại diện XML của mã

Nếu bạn muốn có một giải pháp Pythonian hơn bạn cũng có thể tìm kiếm một yacc ngữ pháp C++ và sử dụng py-ply (Yacc cho Python), nhưng dường như giải pháp cần nhiều công việc hơn

5

Trong nhiều năm, tôi đã sử dụng pygccxml, một trình bao bọc Python rất đẹp mắt xung quanh GCC-XML. Đó là một gói rất đầy đủ tính năng tạo thành cơ sở của một số công cụ tạo mã được sử dụng tốt ngoài đó chẳng hạn như py++ là từ cùng một tác giả.

Các vấn đề liên quan