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

它们只是作为自己的“令牌”与许多空字符串一起返回。

第一个 arg tosplit应该匹配分隔标记的内容,但这显然不是您提供的。由于实际上没有字符分隔标记,因此它必须是匹配零个字符的东西。这意味着需要使用前瞻和/或后瞻。

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 回答