DMS Software Reengineering Toolkit có a C front end (và C++ cuối phía trước) của chúng tôi rằng:
- phân tích cú pháp (compilable) mã nguồn C trong một loạt các các phương ngữ thành AST,
- duy trì các chỉ thị tiền xử lý trong hầu hết các trường hợp như các nút AST
- có thể tạo lại mã C có thể đồng bộ (có nhận xét và chỉ thị tiền xử lý) từ AST s
- có thể thu thập hàng ngàn tập tin trong một hình ảnh duy nhất để cho phép phân tích chéo tập tin và chuyển đổi
- cung cấp đầy đủ xây dựng bảng biểu tượng và truy cập
- cung cấp truy cập thủ tục để ASTs với một thư viện AST thao tác lớn, bao gồm điều hướng, kiểm tra , chèn, xóa, thay thế, kết hợp, ...
- cung cấp nguồn-to-nguồn biến đổi sử dụng các mẫu viết bằng các ký hiệu C phù hợp so với ASTs
Đối với C (chưa cho C++), DMS cũng cung cấp:
- điều khiển và dữ liệu phân tích dòng địa phương và toàn cầu điểm để phân tích
- xây dựng đồ thị cuộc gọi toàn cầu
DMS đã được sử dụng để xử lý các ứng dụng C cực lớn với mục đích trích xuất các sự kiện và tạo ra mã nguồn mới, có nguồn gốc từ cơ sở nguồn gốc.
(EDIT: Feb 2016)
Nó có thể xử lý ví dụ của OP (với các sửa chữa nhỏ để làm cho nó hợp lệ). Đây là nguồn hơi sửa đổi:
#define FILENAME "filename"
#include <stdio.h>
FILE *f;
main() {
f=0;
if (file_is_open) {
#ifdef CAN_OPEN_IT
f = fopen(FILENAME, "r");
#else
printf("Unable to open file.\n");
#endif
}
}
Đây là AST sản xuất:
C~GCC4 Domain Parser Version 3.0.1(28449)
Copyright (C) 1996-2013 Semantic Designs, Inc; All Rights Reserved; SD Confidential
Powered by DMS (R) Software Reengineering Toolkit
AST Optimizations: remove constant tokens, remove unary productions, compact sequences
Using encoding Unicode-UTF-8?ANSI +CRLF +1 /^I
([email protected]~GCC4=2#4a7e0e0^0 Line 1 Column 1 File C:/temp/test.c
([email protected]~GCC4=605#4a77580^1#4a7e0e0:1 {4} Line 1 Column 1 File C:/temp/test.c
([email protected]~GCC4=1094#4a775c0^1#4a77580:1 Line 1 Column 1 File C:/temp/test.c
('#'@C~GCC4=1548#4a771c0^1#4a775c0:1[Keyword:0] Line 1 Column 1 File C:/temp/test.c)'#'
([email protected]~GCC4=1531#4a77200^1#4a775c0:2[`FILENAME'] Line 1 Column 9 File C:/temp/test.c)IDENTIFIER
(<!MacroDefinition>@C~GCC4=1603#4a77180^2#4a775c0:3#4a7f300:1[`FILENAME'] Line 1 Column 18 File C:/temp/test.c
$VOID$ [Child 1]
|([email protected]~GCC4=1525#4a77160^2#4a77180:2#4a7f300:2[`filename'] Line 1 Column 18 File C:/temp/test.c)STRING_LITERAL
$VOID$ [Child 3]
)<!MacroDefinition>#4a77180
([email protected]~GCC4=1578#4a77260^1#4a775c0:4[Keyword:0] Line 1 Column 28 File C:/temp/test.c)new_line
)control_line#4a775c0
([email protected]~GCC4=1104#4a77460^1#4a77580:2 Line 2 Column 1 File C:/temp/test.c
('#'@C~GCC4=1548#4a77340^1#4a77460:1[Keyword:0] Line 2 Column 1 File C:/temp/test.c)'#'
([email protected]~GCC4=1589#4a77380^1#4a77460:2[`stdio.h'] Line 2 Column 10 File C:/temp/test.c)ANGLED_HEADER_NAME
([email protected]~GCC4=1578#4a773c0^1#4a77460:3[Keyword:0] Line 2 Column 19 File C:/temp/test.c)new_line
)control_line#4a77460
([email protected]~GCC4=631#4a774c0^1#4a77580:3 Line 4 Column 1 File C:/temp/test.c
([email protected]~GCC4=1531#4a77360^1#4a774c0:1[`FILE'] Line 4 Column 1 File C:/temp/test.c)IDENTIFIER
([email protected]~GCC4=850#4a77520^1#4a774c0:2 Line 4 Column 6 File C:/temp/test.c
|([email protected]~GCC4=866#4a77560^1#4a77520:1 Line 4 Column 6 File C:/temp/test.c)ptr_operator
|([email protected]~GCC4=1531#4a77480^1#4a77520:2[`f'] Line 4 Column 7 File C:/temp/test.c)IDENTIFIER
)declarator#4a77520
)simple_declaration#4a774c0
([email protected]~GCC4=966#4a77be0^1#4a77580:4 Line 5 Column 1 File C:/temp/test.c
([email protected]~GCC4=852#4a77440^1#4a77be0:1 Line 5 Column 1 File C:/temp/test.c
|([email protected]~GCC4=1531#4a774e0^1#4a77440:1[`main'] Line 5 Column 1 File C:/temp/test.c)IDENTIFIER
|([email protected]~GCC4=900#4a77220^1#4a77440:2 Line 5 Column 6 File C:/temp/test.c)parameter_declaration_clause
)direct_declarator#4a77440
([email protected]~GCC4=507#4a77b20^1#4a77be0:2 Line 5 Column 8 File C:/temp/test.c
|([email protected]~GCC4=511#4a77d20^1#4a77b20:1 {2} Line 6 Column 3 File C:/temp/test.c
| (AMBIGUITY<statement=358>@C~GCC4=1602#4a77680^1#4a77d20:1{2} Line 6 Column 3 File C:/temp/test.c
| ([email protected]~GCC4=503#4a7e040^1#4a77680:1 Line 6 Column 3 File C:/temp/test.c
| ([email protected]~GCC4=457#4a77f00^1#4a7e040:1 Line 6 Column 3 File C:/temp/test.c
| |([email protected]~GCC4=470#4a77a00^1#4a77f00:1 Line 6 Column 3 File C:/temp/test.c
| | ([email protected]~GCC4=1531#4a77400^2#4a77a00:1#4a77fc0:1[`f'] Line 6 Column 3 File C:/temp/test.c)IDENTIFIER
| |)assignment_target#4a77a00
| |([email protected]~GCC4=1471#4a77a60^2#4a77f00:2#4a77f60:1[0] Line 6 Column 5 File C:/temp/test.c)INT_LITERAL
| )assignment_expression#4a77f00
| )expression_statement#4a7e040
| ([email protected]~GCC4=630#4a7e060^1#4a77680:2 Line 6 Column 3 File C:/temp/test.c
| ([email protected]~GCC4=835#4a77fc0^1#4a7e060:1 Line 6 Column 3 File C:/temp/test.c
| |(IDEN[email protected]~GCC4=1531#4a77400^2... [ALREADY PRINTED] ...)
| |([email protected]~GCC4=983#4a77f60^1#4a77fc0:2 Line 6 Column 4 File C:/temp/test.c
| | ([email protected]~GCC4=1471#4a77a60^2... [ALREADY PRINTED] ...)
| |)initializer#4a77f60
| )init_declarator#4a77fc0
| )simple_declaration#4a7e060
|)AMBIGUITY#4a77680
| ([email protected]~GCC4=527#4a77b40^1#4a77d20:2 Line 7 Column 1 File C:/temp/test.c
| ([email protected]~GCC4=1531#4a7e0c0^1#4a77b40:1[`file_is_open'] Line 7 Column 5 File C:/temp/test.c)IDENTIFIER
| ([email protected]~GCC4=507#4a77ae0^1#4a77b40:2 Line 7 Column 19 File C:/temp/test.c
| ([email protected]~GCC4=490#4a7f840^1#4a77ae0:1 Line 8 Column 1 File C:/temp/test.c
| |([email protected]~GCC4=1088#4a7f1c0^1#4a7f840:1 Line 8 Column 1 File C:/temp/test.c
| | ('#'@C~GCC4=1548#4a7f240^1#4a7f1c0:1[Keyword:0] Line 8 Column 1 File C:/temp/test.c)'#'
| | ([email protected]~GCC4=1531#4a7ee60^1#4a7f1c0:2[`CAN_OPEN_IT'] Line 8 Column 8 File C:/temp/test.c)IDENTIFIER
| | ([email protected]~GCC4=1578#4a7f1e0^1#4a7f1c0:3[Keyword:0] Line 8 Column 19 File C:/temp/test.c)new_line
| |)if_directive#4a7f1c0
| |(AMBIGUITY<statement=358>@C~GCC4=1602#4a77d40^1#4a7f840:2{2} Line 9 Column 5 File C:/temp/test.c
| | ([email protected]~GCC4=503#4a7f4a0^1#4a77d40:1 Line 9 Column 5 File C:/temp/test.c
| | ([email protected]~GCC4=457#4a7f3c0^1#4a7f4a0:1 Line 9 Column 5 File C:/temp/test.c
| | ([email protected]~GCC4=470#4a7eec0^1#4a7f3c0:1 Line 9 Column 5 File C:/temp/test.c
| | |([email protected]~GCC4=1531#4a7eee0^2#4a7eec0:1#4a7f400:1[`f'] Line 9 Column 5 File C:/temp/test.c)IDENTIFIER
| | )assignment_target#4a7eec0
| | ([email protected]~GCC4=201#4a7f2e0^1#4a7f3c0:2 Line 9 Column 9 File C:/temp/test.c
| | |([email protected]~GCC4=1531#4a7f120^2#4a7f2e0:1#4a7f160:1[`fopen'] Line 9 Column 9 File C:/temp/test.c)IDENTIFIER
| | |([email protected]~GCC4=228#4a7f260^2#4a7f2e0:2#4a7f160:2 Line 9 Column 15 File C:/temp/test.c
| | | (<!MacroCall>@C~GCC4=1607#4a7f300^1#4a7f260:1[`FILENAME'] Line 9 Column 15 File C:/temp/test.c
| | | (<!MacroDefinition>@C~GCC4=1603#4a77180^2... [ALREADY PRINTED] ...)
| | | ([email protected]~GCC4=1525#4a77160^2... [ALREADY PRINTED] ...)
| | | $VOID$ [Child 3]
| | | ([email protected]~GCC4=1525#4a7f2c0^1#4a7f300:4[`filename'] Line 1 Column 18 File C:/temp/test.c)STRING_LITERAL
| | | $VOID$ [Child 5]
| | |)<!MacroCall>#4a7f300
| | | ([email protected]~GCC4=1525#4a7f140^1#4a7f260:2[`r'] Line 9 Column 25 File C:/temp/test.c)STRING_LITERAL
| | |)expression_list#4a7f260
| | )postfix_expression#4a7f2e0
| | )assignment_expression#4a7f3c0
| |)expression_statement#4a7f4a0
| | ([email protected]~GCC4=630#4a7f480^1#4a77d40:2 Line 9 Column 5 File C:/temp/test.c
| | ([email protected]~GCC4=835#4a7f400^1#4a7f480:1 Line 9 Column 5 File C:/temp/test.c
| | ([email protected]~GCC4=1531#4a7eee0^2... [ALREADY PRINTED] ...)
| | ([email protected]~GCC4=983#4a7f3e0^1#4a7f400:2 Line 9 Column 7 File C:/temp/test.c
| | |([email protected]~GCC4=201#4a7f160^1#4a7f3e0:1 Line 9 Column 9 File C:/temp/test.c
| | | ([email protected]~GCC4=1531#4a7f120^2... [ALREADY PRINTED] ...)
| | | ([email protected]~GCC4=228#4a7f260^2... [ALREADY PRINTED] ...)
| | |)postfix_expression#4a7f160
| | )initializer#4a7f3e0
| | )init_declarator#4a7f400
| |)simple_declaration#4a7f480
| |)AMBIGUITY#4a77d40
| |([email protected]~GCC4=1091#4a7f4c0^1#4a7f840:3 Line 10 Column 1 File C:/temp/test.c
| | ('#'@C~GCC4=1548#4a7f500^1#4a7f4c0:1[Keyword:0] Line 10 Column 1 File C:/temp/test.c)'#'
| | ([email protected]~GCC4=1578#4a7f4e0^1#4a7f4c0:2[Keyword:0] Line 10 Column 6 File C:/temp/test.c)new_line
| |)else_directive#4a7f4c0
| |([email protected]~GCC4=503#4a7f7c0^1#4a7f840:4 Line 11 Column 5 File C:/temp/test.c
| | ([email protected]~GCC4=201#4a77ba0^1#4a7f7c0:1 Line 11 Column 5 File C:/temp/test.c
| | ([email protected]C~GCC4=1531#4a7f640^1#4a77ba0:1[`printf'] Line 11 Column 5 File C:/temp/test.c)IDENTIFIER
| | ([email protected]~GCC4=1525#4a77c20^1#4a77ba0:2[`Unable to open file.
'] Line 11 Column 12 File C:/temp/test.c)STRING_LITERAL
| |)postfix_expression#4a77ba0
| |)expression_statement#4a7f7c0
| |([email protected]~GCC4=1092#4a7f7e0^1#4a7f840:5 Line 12 Column 1 File C:/temp/test.c
| | ('#'@C~GCC4=1548#4a7f720^1#4a7f7e0:1[Keyword:0] Line 12 Column 1 File C:/temp/test.c)'#'
| | ([email protected]~GCC4=1578#4a7f700^1#4a7f7e0:2[Keyword:0] Line 12 Column 7 File C:/temp/test.c)new_line
| |)endif_directive#4a7f7e0
| )statement#4a7f840
| )compound_statement#4a77ae0
|)selection_statement#4a77b40
|)statement_seq#4a77d20
)compound_statement#4a77b20
)function_definition#4a77be0
)declaration_seq#4a77580
)translation_unit#4a7e0e0
Bạn có thể thấy các chỉ thị tiền xử lý là "if_directive" trên dòng 8.
Vâng, DMS có thể prettyprint cái cây này nữa. Lệnh sau chạy trình phân tích cú pháp để tạo ra một AST, và sau đó chạy trình gỡ rối DMS để tạo nguồn chỉ từ cây. Chuyến đi khứ hồi là chính xác; bạn có thể biên dịch lại và nhận được kết quả tương tự. Bình luận cũng được bảo tồn.
C:\DMS\Domains\C\GCC4\Tools\PrettyPrinter>run domainprettyprinter \temp\test.c
C~GCC4 PrettyPrinter Version 1.2.13
Copyright (C) 2004-2013 Semantic Designs, Inc; All Rights Reserved; SD Confidential
Powered by DMS (R) Software Reengineering Toolkit
#define FILENAME "filename"
#include <stdio.h>
FILE *f;
main()
{
f = 0;
if (file_is_open)
{
#ifdef CAN_OPEN_IT
f = fopen(FILENAME, "r");
#else
printf("Unable to open file.\n");
#endif
}
}
You can see how DMS handles C++. Tại thời điểm này, nó xử lý tất cả C++ 14 cho các phương ngữ GCC và MS.
Nguồn
2010-01-31 21:43:16
Cảm ơn, có vẻ như nó nằm dọc theo đường thẳng. – Steve
Tôi không tin rằng Clang bắt chỉ thị tiền xử lý trong các AST của nó. –