OP说:我不介意使用任何工具从Objective-C代码中提取AST...
我们的DMS软件重构工具包可以为Objective-C完成此操作。
对于DMS生成的解析器"domainparser",可以使用以下命令行:
run \DMS\Domains\C\ObjectiveCv2\Tools\Parser\domainparser ++AST "C:\temp\test.m"
这个 Objective C 文件 "test.m":
@implementation GTLClientLoginAuthorizationArgs
@synthesize request = request_,
delegate = delegate_,
selector = sel_,
completionHandler = completionHandler_,
thread = thread_,
error = error_;
+ (GTLClientLoginAuthorizationArgs *)argsWithRequest:(NSMutableURLRequest *)req
delegate:(id)delegate
selector:(SEL)sel
completionHandler:(id)completionHandler
thread:(NSThread *)thread {
GTLClientLoginAuthorizationArgs *obj;
obj = [[[GTLClientLoginAuthorizationArgs alloc] init] autorelease];
obj.request = req;
obj.delegate = delegate;
obj.selector = sel;
obj.completionHandler = completionHandler;
obj.thread = thread;
return obj;
}
- (void)dealloc {
self.request = nil;
self.delegate = nil;
self.selector = NULL;
self.completionHandler = nil;
self.thread = nil;
self.error = nil;
[super dealloc];
}
@end
使用AST生成此输出:
Domain Parser for C~ObjectiveCv2 2.4.4
Copyright (C) Semantic Designs 1996-2012
(translation_unit@C~ObjectiveCv2=2
(class_implementation@C~ObjectiveCv2=1048
(IDENTIFIER@C~ObjectiveCv2=1270
(super_class_option@C~ObjectiveCv2=1046
(instance_variables@C~ObjectiveCv2=1061
(implementation_definition_list@C~ObjectiveCv2=1079
(implementation_definition_list@C~ObjectiveCv2=1079
|(implementation_definition_list@C~ObjectiveCv2=1079
| (implementation_definition_list@C~ObjectiveCv2=1078
| (property_implementation@C~ObjectiveCv2=1131
| (property_synthesize_list@C~ObjectiveCv2=1134
| (property_synthesize_list@C~ObjectiveCv2=1134
| |(property_synthesize_list@C~ObjectiveCv2=1134
| | (property_synthesize_list@C~ObjectiveCv2=1134
| | (property_synthesize_list@C~ObjectiveCv2=1134
| | (property_synthesize_list@C~ObjectiveCv2=1133
| | |(property_synthesize_item@C~ObjectiveCv2=1136
| | | (IDENTIFIER@C~ObjectiveCv2=1270
| | | (IDENTIFIER@C~ObjectiveCv2=1270
| | |)property_synthesize_item
| | )property_synthesize_list
| | (property_synthesize_item@C~ObjectiveCv2=1136
| | |(IDENTIFIER@C~ObjectiveCv2=1270
| | |(IDENTIFIER@C~ObjectiveCv2=1270
| | )property_synthesize_item
| | )property_synthesize_list
| | (property_synthesize_item@C~ObjectiveCv2=1136
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | )property_synthesize_item
| | )property_synthesize_list
| | (property_synthesize_item@C~ObjectiveCv2=1136
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | )property_synthesize_item
| |)property_synthesize_list
| |(property_synthesize_item@C~ObjectiveCv2=1136
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | (IDENTIFIER@C~ObjectiveCv2=1270
| |)property_synthesize_item
| )property_synthesize_list
| (property_synthesize_item@C~ObjectiveCv2=1136
| |(IDENTIFIER@C~ObjectiveCv2=1270
| |(IDENTIFIER@C~ObjectiveCv2=1270
| )property_synthesize_item
| )property_synthesize_list
| )property_implementation
|)implementation_definition_list
|(class_method_definition@C~ObjectiveCv2=1087
| (method_type@C~ObjectiveCv2=1103
| (type_id@C~ObjectiveCv2=647
| (AMBIGUITY<type_specifier=388>@C~ObjectiveCv2=1390
| |(type_specifier@C~ObjectiveCv2=1144
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | (protocol_option@C~ObjectiveCv2=1057
| |)type_specifier
| |(IDENTIFIER@C~ObjectiveCv2=1270
| )AMBIGUITY
| (ptr_operator@C~ObjectiveCv2=640
| )type_id
| )method_type
| (keyword_selector@C~ObjectiveCv2=1095
| (keyword_selector@C~ObjectiveCv2=1095
| (keyword_selector@C~ObjectiveCv2=1095
| |(keyword_selector@C~ObjectiveCv2=1095
| | (keyword_selector@C~ObjectiveCv2=1094
| | (keyword_declarator@C~ObjectiveCv2=1099
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | (method_type@C~ObjectiveCv2=1103
| | |(type_id@C~ObjectiveCv2=647
| | | (AMBIGUITY<type_specifier=388>@C~ObjectiveCv2=1390
| | | (type_specifier@C~ObjectiveCv2=1144
| | | (IDENTIFIER@C~ObjectiveCv2=1270
| | | (protocol_option@C~ObjectiveCv2=1057
| | | )type_specifier
| | | (IDENTIFIER@C~ObjectiveCv2=1270
| | | )AMBIGUITY
| | | (ptr_operator@C~ObjectiveCv2=640
| | |)type_id
| | )method_type
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | )keyword_declarator
| | )keyword_selector
| | (keyword_declarator@C~ObjectiveCv2=1099
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | (method_type@C~ObjectiveCv2=1103
| | (type_specifier@C~ObjectiveCv2=1143
| | |(protocol_option@C~ObjectiveCv2=1057
| | )type_specifier
| | )method_type
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | )keyword_declarator
| |)keyword_selector
| |(keyword_declarator@C~ObjectiveCv2=1099
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | (method_type@C~ObjectiveCv2=1103
| | (simple_type_specifier@C~ObjectiveCv2=1141
| | )method_type
| | (IDENTIFIER@C~ObjectiveCv2=1270
| |)keyword_declarator
| )keyword_selector
| (keyword_declarator@C~ObjectiveCv2=1099
| |(IDENTIFIER@C~ObjectiveCv2=1270
| |(method_type@C~ObjectiveCv2=1103
| | (type_specifier@C~ObjectiveCv2=1143
| | (protocol_option@C~ObjectiveCv2=1057
| | )type_specifier
| |)method_type
| |(IDENTIFIER@C~ObjectiveCv2=1270
| )keyword_declarator
| )keyword_selector
| (keyword_declarator@C~ObjectiveCv2=1099
| (IDENTIFIER@C~ObjectiveCv2=1270
| (method_type@C~ObjectiveCv2=1103
| |(type_id@C~ObjectiveCv2=647
| | (AMBIGUITY<type_specifier=388>@C~ObjectiveCv2=1390
| | (type_specifier@C~ObjectiveCv2=1144
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | (protocol_option@C~ObjectiveCv2=1057
| | )type_specifier
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | )AMBIGUITY
| | (ptr_operator@C~ObjectiveCv2=640
| |)type_id
| )method_type
| (IDENTIFIER@C~ObjectiveCv2=1270
| )keyword_declarator
| )keyword_selector
| (declaration_star@C~ObjectiveCv2=1085
| (compound_statement@C~ObjectiveCv2=403
| (statement_seq@C~ObjectiveCv2=405
| (AMBIGUITY<statement=332>@C~ObjectiveCv2=1390
| |(expression_statement@C~ObjectiveCv2=400
| | (multiplicative_expression@C~ObjectiveCv2=209
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | )multiplicative_expression
| |)expression_statement
| |(simple_declaration@C~ObjectiveCv2=515
| | (AMBIGUITY<type_specifier=388>@C~ObjectiveCv2=1390
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | (type_specifier@C~ObjectiveCv2=1144
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | (protocol_option@C~ObjectiveCv2=1057
| | )type_specifier
| | )AMBIGUITY
| | (declarator@C~ObjectiveCv2=624
| | (ptr_operator@C~ObjectiveCv2=640
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | )declarator
| |)simple_declaration
| )AMBIGUITY
| (expression_statement@C~ObjectiveCv2=400
| |(assignment_expression@C~ObjectiveCv2=356
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | (primary_expression@C~ObjectiveCv2=1158
| | (primary_expression@C~ObjectiveCv2=1158
| | (primary_expression@C~ObjectiveCv2=1158
| | |(IDENTIFIER@C~ObjectiveCv2=1270
| | |(IDENTIFIER@C~ObjectiveCv2=1270
| | )primary_expression
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | )primary_expression
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | )primary_expression
| |)assignment_expression
| )expression_statement
| (expression_statement@C~ObjectiveCv2=400
| |(assignment_expression@C~ObjectiveCv2=356
| | (postfix_expression@C~ObjectiveCv2=130
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | )postfix_expression
| | (IDENTIFIER@C~ObjectiveCv2=1270
| |)assignment_expression
| )expression_statement
| (expression_statement@C~ObjectiveCv2=400
| |(assignment_expression@C~ObjectiveCv2=356
| | (postfix_expression@C~ObjectiveCv2=130
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | )postfix_expression
| | (IDENTIFIER@C~ObjectiveCv2=1270
| |)assignment_expression
| )expression_statement
| (expression_statement@C~ObjectiveCv2=400
| |(assignment_expression@C~ObjectiveCv2=356
| | (postfix_expression@C~ObjectiveCv2=130
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | )postfix_expression
| | (IDENTIFIER@C~ObjectiveCv2=1270
| |)assignment_expression
| )expression_statement
| (expression_statement@C~ObjectiveCv2=400
| |(assignment_expression@C~ObjectiveCv2=356
| | (postfix_expression@C~ObjectiveCv2=130
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | )postfix_expression
| | (IDENTIFIER@C~ObjectiveCv2=1270
| |)assignment_expression
| )expression_statement
| (expression_statement@C~ObjectiveCv2=400
| |(assignment_expression@C~ObjectiveCv2=356
| | (postfix_expression@C~ObjectiveCv2=130
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | (IDENTIFIER@C~ObjectiveCv2=1270
| | )postfix_expression
| | (IDENTIFIER@C~ObjectiveCv2=1270
| |)assignment_expression
| )expression_statement
| (jump_statement@C~ObjectiveCv2=487
| |(IDENTIFIER@C~ObjectiveCv2=1270
| )jump_statement
| )statement_seq
| )compound_statement
|)class_method_definition
)implementation_definition_list
(instance_method_definition@C~ObjectiveCv2=1088
|(AMBIGUITY<method_result_option=527>@C~ObjectiveCv2=1390
| (method_result_option@C~ObjectiveCv2=1101
| (method_type@C~ObjectiveCv2=1103
| (simple_type_specifier@C~ObjectiveCv2=545
| )method_type
|)AMBIGUITY
|(IDENTIFIER@C~ObjectiveCv2=1270
|(declaration_star@C~ObjectiveCv2=1085
|(compound_statement@C~ObjectiveCv2=403
| (statement_seq@C~ObjectiveCv2=405
| (expression_statement@C~ObjectiveCv2=400
| (assignment_expression@C~ObjectiveCv2=356
| |(postfix_expression@C~ObjectiveCv2=130
| | (primary_expression@C~ObjectiveCv2=1155
| | (IDENTIFIER@C~ObjectiveCv2=1270
| |)postfix_expression
| |(primary_expression@C~ObjectiveCv2=1157
| )assignment_expression
| )expression_statement
| (expression_statement@C~ObjectiveCv2=400
| (assignment_expression@C~ObjectiveCv2=356
| |(postfix_expression@C~ObjectiveCv2=130
| | (primary_expression@C~ObjectiveCv2=1155
| | (IDENTIFIER@C~ObjectiveCv2=1270
| |)postfix_expression
| |(primary_expression@C~ObjectiveCv2=1157
| )assignment_expression
| )expression_statement
| (expression_statement@C~ObjectiveCv2=400
| (assignment_expression@C~ObjectiveCv2=356
| |(postfix_expression@C~ObjectiveCv2=130
| | (primary_expression@C~ObjectiveCv2=1155
| | (IDENTIFIER@C~ObjectiveCv2=1270
| |)postfix_expression
| |(IDENTIFIER@C~ObjectiveCv2=1270
| )assignment_expression
| )expression_statement
| (expression_statement@C~ObjectiveCv2=400
| (assignment_expression@C~ObjectiveCv2=356
| |(postfix_expression@C~ObjectiveCv2=130
| | (primary_expression@C~ObjectiveCv2=1155
| | (IDENTIFIER@C~ObjectiveCv2=1270
| |)postfix_expression
| |(primary_expression@C~ObjectiveCv2=1157
| )assignment_expression
| )expression_statement
| (expression_statement@C~ObjectiveCv2=400
| (assignment_expression@C~ObjectiveCv2=356
| |(postfix_expression@C~ObjectiveCv2=130
| | (primary_expression@C~ObjectiveCv2=1155
| | (IDENTIFIER@C~ObjectiveCv2=1270
| |)postfix_expression
| |(primary_expression@C~ObjectiveCv2=1157
| )assignment_expression
| )expression_statement
| (expression_statement@C~ObjectiveCv2=400
| (assignment_expression@C~ObjectiveCv2=356
| |(postfix_expression@C~ObjectiveCv2=130
| | (primary_expression@C~ObjectiveCv2=1155
| | (IDENTIFIER@C~ObjectiveCv2=1270
| |)postfix_expression
| |(primary_expression@C~ObjectiveCv2=1157
| )assignment_expression
| )expression_statement
| (expression_statement@C~ObjectiveCv2=400
| (primary_expression@C~ObjectiveCv2=1158
| |(primary_expression@C~ObjectiveCv2=1156
| |(IDENTIFIER@C~ObjectiveCv2=1270
| )primary_expression
| )expression_statement
| )statement_seq
|)compound_statement
)instance_method_definition
)implementation_definition_list
)class_implementation
)translation_unit
Exiting with final status 0
因为树的形状与我们使用的语法同构,所以语法就是文档。请参见之前的SO答案如何做到这一点,同时生成AST。
这是从一个流行库中提取的代码片段;它只是一个片段,否则树会非常庞大。我还稍微作弊了一点,省略了#导入,这让我可以运行一个易于配置的解析器。DMS将解析包含#includes的文件,并保留指令或保留包含文本,具体取决于其解析器的配置。
这是针对ObjectiveC而不是ObjectiveC++的。我们正在努力改进 :-}
DMS为操作其生成的AST的程序分析提供了很多额外的支持。