2

c関数の宣言を解析しようとしています。文字列からトークンの配列を取得したい。だから私は分割を使用します:

$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[]", ")"]

オプションはありますか?(私自身の字句パーサーを書く代わりに)

4

2 に答える 2

4

まず、スペースは削除されません。それらは返却されています。

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

それらは、多くの空の文字列とともに、独自の「トークン」として返されるだけです。

最初の引数splitは、トークンを区切るものと一致する必要がありますが、それは明らかにあなたが提供したものではありません。実際にはトークンを区切る文字はないため、ゼロ文字に一致するものにする必要があります。つまり、先読みおよび/または後読みを使用する必要があります。

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

以下を提供します(これはまさにあなたが求めたものです):

'int ',
'func1',
'(  ',
'int ',
'*   ',
', ',
'const   ',
'float',
', ',
'const ',
'char[]',
')'
于 2013-02-25T13:45:12.873 に答える
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;
  }
于 2013-02-25T13:42:04.283 に答える