2013-02-25 104 views
2

我想解析c函數聲明。我想從字符串中獲取令牌數組。 所以我用分裂:Perl拆分()不刪除分隔符

$function = "int func1( int * , const float, const char[])" 
print split(/(\(|\)|\*|[|]|,|\)/, $function); 

它返回的這個

["int" "func1", "(", "int", "*", ",", "const", "float", ",", "const", "char[]", ")"] 

這是basicly正確的數組,但我需要不把空格去掉。所以我期望這樣的事情

["int " "func1", "( ", "int ", "* ", ", ", "const ", "float", ", ", "const ", "char[]", ")"] 

我有什麼選擇嗎? (而不是寫我自己的詞法分析器)

+0

你看CPAN?你幾乎可以肯定不需要自己寫,但是用'split'天真地寫自己的東西似乎是個不錯的主意。 – geoffspear 2013-02-25 13:37:05

回答

4

對於初學者來說,它不會刪除的空間。他們正在退回。

'int',' ','func1','(','',' ','',' ','int',' ','','*','',' ','',' ','',' ','',',','',' ','const',' ','',' ','',' ','float',',','',' ','const',' ','char[]',')' 

他們只是返回作爲自己的「令牌」,有許多空字符串一起。

split的第一個參數應與匹配令牌的內容相匹配,但顯然不是您提供的內容。由於沒有字符實際上將令牌分開,所以它必須是匹配零個字符的東西。這意味着需要使用前視和/或後視。

split /(?=[()*|,])|(?<=[()*,])(?!)/ 

將提供以下(這正是你問什麼):

'int ', 
'func1', 
'( ', 
'int ', 
'* ', 
', ', 
'const ', 
'float', 
', ', 
'const ', 
'char[]', 
')' 
+0

可能它的不完美,如果我試試這個:「int *(* func3(void *(*)(int *,char **(* )(char *,char **))))(const int(*)[10])「)。它返回這個非常接近解決方案的http://prntscr.com/u3vvn。你能寫出更好的一點嗎?無論如何非常感謝 – l0v3 2013-02-25 14:01:37

+0

@ l0v3,修正了它。你想到的是一樣的。 – ikegami 2013-02-25 15:34:05

+0

謝謝你,我刪除了我的帖子:) – l0v3 2013-02-25 21:38:49

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; 
    } 
+0

不幸的是,它的一個學校項目和這個庫應該幫助我太多:/ – l0v3 2013-02-25 14:03:00