如何从源文件中获取C风格的函数?

时间:2015-03-16 11:51:37

标签: regex parsing lexer

我需要阅读源文件并查找所有c / c ++函数并将它们用于进一步处理。用PHP和regexp

试了一下
$patt = '/([a-z ]*?)(\w+?)\s*(\(.*?\))\s*(\{.*\})/s';

但看起来错误的方式。最好的方法是什么?

这是我需要获得的功能示例:

int main(int argc, char **argv){
   int a=11112,baa=3,c;
   int a[] ={1,32,3,4,535,35,3,114};
   c=a+b;
}

正如您所看到的那样,114};曲线破坏了正则表达式。所以我认为这是一个更好的解决方案。

1 个答案:

答案 0 :(得分:1)

简介

评论中有许多提示,使用正则表达式匹配无法完成,必须通过使用更强大的工具进行解析来完成,但尚未真正解释为什么会这样,或者甚至为什么解析与正则表达式不同匹配。它可能会给读者留下一个印象,即如果一个人非常努力你可以做到这一点,或者如果你非常聪明那么你也可以做到这一点。这不是真的,但需要详细解释才能真正理解原因。

理解这样的问题是良好的计算机科学教育的一个要素,在某种程度上,像你这样的问题经常被设置为试题,以使学生能够理解应用于编程问题的理论。弱小的学生将尝试写正则表达式,而强大的学生将证明为什么不可能。

这些问题也说明了为什么只是一个优秀且经验丰富的程序员还不够好。无论有多少年的编程和计算机经验,没有遇到理论,这仍然是一个不可解决的问题。我也感到遗憾的是,一些现代计算机科学学位课程,专注于实际任务,如应用程序和现代平台的创建,往往忽略了这一关键元素。

背景

所以理论。我们引用了Noam Chomsky和他的Language Hierarchy的工作。这概述了不同级别的语言规范机制(语法)并区分了它们的能力。最简单的语法形式称为Chomsky type-3,它代表regular language,我们将其用作regular expressions

正则表达式,无论实现或符号,都能够指定重复的符号序列。由重复符号模式形成的任何东西都可以通过正则表达式进行匹配。

我们可以匹配abc s的序列,例如(+):

(a|b|c)*              --- any number of a,b,c's in any order
a*b*c*                --- any number of a,b,c's in order
(abc|cba|bac|cab)*    --- any number of a,b,c's in equal number

然而,我们做不到的一件事是按照特定的顺序写一个相同数量的a,b,c的模式,例如:

aabbcc, aaabbbccc 

这也适用于括号等符号:

[[bb]], {{{bbb}}}, ((((bbbb))))

常规语法不能做的是指定正确的嵌套。需要一种更强大的机制。更强大的机制被称为乔姆斯基2型语言,或context free grammars。 (*)我们通常会在BNF或类似的某些表示法中将这些作为语法规则来体验。我们可以像这样处理嵌套:

exp -> ( exp ) | id
id  -> a | b | c

然后,这给了我们想要的相同数量的开括号和近括号。

问题

所以,让我们回到最初的问题。我们如何匹配 C / C ++函数?如果语言只允许函数看起来像这样:

type name (type1 parameter1, type2 parameter2, ...) {
 ... body ...
 }

你的正则表达式会这样做,但正如你所注意到的,函数内部的结构可以包含需要某些东西可以处理嵌套的{}对。有时在这一点上,一些程序员认为他们可以编写代码来计算open {和close }的数量,并避免使用语法和解析器。但是,没有多少例子来说明这种方法的缺陷。考虑:

my function (an arg) { /* } */ arg = "{"; outch('{'); /* } */ }

这表明并非所有符号都会被平等嵌套。

因此,要识别像 C / C ++这样的语言中的函数,必须使用一组规则几乎完全解析(处理)语言的几乎所有结构。语言。要做到这一点,通常需要使用解析器生成器工具,例如注释中建议的。 Bison,yacc,antlr等都是这类工具的例子。

摘要

在解释为什么这是一个确定计算机科学中一个特别特殊问题的问题时,我希望提问者和新手程序员能避免类似的错误,并导致正确的知识,使他们的问题得以解决。更好的是,它可能会引导一些人更新他们对计算机技术这一重要领域的知识。

<小时/> [+]我只是在我的记忆中输入这个,而不是从教科书中输入。如果我对这个例子的性质或细节犯了错误,我道歉。我最喜欢的关于这些材料的例子和解释的书是:Cleaveland, J.C & Uzgalis, R.C. (1976) Grammars for Programming Languages。如果你有一个,你就是一个幸运的人 (*)对于那些知道语法与其产生的语言之间的矛盾差异的人,我为术语的模糊而道歉。