我正在尝试解析c函数声明。我想从字符串中获取令牌数组。 所以我使用split:
$function = "int func1( int * , const float, const char[])"
print split(/(\(|\)|\*|[|]|,|\ )/, $function);
它返回此
的数组["int" "func1", "(", "int", "*", ",", "const", "float", ",", "const", "char[]", ")"]
这是基本正确的,但我不需要删除空格。所以我期待这样的事情
["int " "func1", "( ", "int ", "* ", ", ", "const ", "float", ", ", "const ", "char[]", ")"]
有任何选择吗? (而不是写我自己的词法解析器)
答案 0 :(得分:4)
首先,它不会删除空格。他们正在返回。
'int',' ','func1','(','',' ','',' ','int',' ','','*','',' ','',' ','',' ','',',','',' ','const',' ','',' ','',' ','float',',','',' ','const',' ','char[]',')'
它们只是作为自己的“标记”返回,还有许多空字符串。
split
的第一个arg应该与令牌分开的内容匹配,但这显然不是你提供的。由于没有字符实际上将标记分开,因此它必须是匹配零字符的东西。这意味着需要使用前瞻和/或外观。
split /(?=[()*|,])|(?<=[ ()*,])(?! )/
将提供以下内容(这正是您所要求的):
'int ',
'func1',
'( ',
'int ',
'* ',
', ',
'const ',
'float',
', ',
'const ',
'char[]',
')'
答案 1 :(得分:3)
你检查了这些吗?
在Perl中有几种现有的解析C源的方法。
http://search.cpan.org/~dconway/Parse-RecDescent/demo/demo_another_Cgrammar.pl
http://www.perlmonks.org/?node_id=746341
来自示例:
use GCC::TranslationUnit;
# echo '#include <stdio.h>' > stdio.c
# gcc -fdump-translation-unit -c stdio.c
$node = GCC::TranslationUnit::Parser->parsefile('stdio.c.tu')->root;
# list every function/variable name
while($node) {
if($node->isa('GCC::Node::function_decl') or
$node->isa('GCC::Node::var_decl')) {
printf "%s declared in %s\n",
$node->name->identifier, $node->source;
}
} continue {
$node = $node->chain;
}