C / C ++解析器如何工作?

时间:2011-01-21 02:54:14

标签: c parsing compiler-construction cross-compiling

我花了很多时间研究PHP解析器的工作原理:

它将PHP代码转换为最终的c代码。

但是如何将c代码翻译成可执行文件?

顺便说一句,如何判断语言A是否可以从数学方面转换为语言B?

4 个答案:

答案 0 :(得分:10)

这是一个非常伟大且非常深刻的问题,它涉及计算机科学的许多部分。

最终,计算机上的所有程序都通过在机器代码中向处理器发出指令来执行。没有一个“机器代码”,每个处理器都有自己的一组可以执行的指令。这些通常是低级操作,例如“将值加载到内存中”或“将两个值一起添加”。从理论上讲,每个程序都可以用机器代码编写,但这种情况很少见。机器代码本质上是一系列零和一系列由处理器以特定方式解码的,并且以这种方式直接构建任何复杂系统几乎是不可能的。

机器代码上方的一步是汇编语言,这是一种非常低级的宏语言语言,通常与机器代码具有一对一的映射关系。例如,您可能有“add”这样的命令,它们会添加,“sub”代表减法,或者“call”代表函数调用。最终,使用汇编程序将代码转换为机器代码,该程序将程序集转换为机器代码。在装配中构建大型复杂系统是可能的,但这非常困难。

许多编程语言(如C和C ++)都是编译的,这意味着一个名为编译器的特殊程序将源代码转换为汇编语言,然后可以转换直接到机器代码。通过这种方式,您可以编写高级工作的代码 - 它可以包含变量,函数,对象,模板,异常等 - 但可以直接在机器硬件上运行。其他编程语言是解释,这意味着一个称为解释器的特殊程序解析源代码,构建它的一些内存表示,然后将其转换为汇编或间接(通过使用程序来控制执行哪些指令)或直接(通过根据需要生成程序集)。

关于如何从一种语言转换为另一种语言的理论已被广泛研究。有很多挑战,从“您如何查看程序的源代码并了解您正在查看的内容?” “将这个程序转换成其他语言的最有效方法是什么?”前者包括 lexing 解析语义分析;后者涉及优化代码生成

通常情况下,任何语言的程序都可以转换为另一种语言的等效程序,但效率可能会有明显的下降。某些编程语言具有访问底层硬件的特殊功能,因此无法使用无法访问该硬件的语言编写,但这种情况很少发生。程序是否可以用另一种语言重写的一个典型度量是询问这两种语言是否是图灵完备,这是一个数学术语,表示编程语言是否表达足以编码特定类别的函数。

希望这有帮助!

答案 1 :(得分:6)

PHP并没有真正“翻译”为C代码; PHP解释器在运行可执行代码时解释 PHP,PHP解释器是一个知道如何在进程中执行所有PHP的状态机。不需要或不需要中间体C.因为它被解释,所以每次PHP可执行文件解释PHP程序时,都会重新评估它。

PHP解释器是用C语言编写的,但它可能是用C ++或Assembly或Pascal或Erlang或bash或Java或其他任何你想要的。 (我认为它始于Perl,但我的记忆变得模糊。)

C使用编译器编译,在程序运行数千次之前运行一次。大多数C编译器会进行多次“传递”:lexing输入令牌parsing将令牌转换为,然后修改{{3}为每个Abstract Syntax Tree执行生成symbol tables。在对抽象语法树进行各种优化(例如scopesdead code removal)之后,树将传递给static single assignment,这将为输入生成所需的code generator可以在有问题的目标object file上运行。目标文件与architecture链接到未在特定linker中定义的对象(C中的函数和变量),以便程序可以在运行时由translation unit加载。 / p>

linker/loader是学习编译器的最佳来源,但我推荐使用Pragprog的dragon book

答案 2 :(得分:5)

从我的理解,你的主要问题似乎是关于编译过程。正如您在评论中提到的,您对解析器和编译器感到困惑。让我帮你一点:

alt text

解析只是编译过程中的一个步骤。为了更好地理解您的问题,您必须首先了解编译器的工作原理。通常,编译器通常采用上述几个步骤。要理解上述内容将需要一些工作。如果您想进一步深入研究,请阅读this link的讲座。源代码和目标代码取决于上下文。通常源代码是高级语言,目标代码是机器代码。

答案 3 :(得分:2)

  

如何判断语言A是否可以   从某种程度上转换为语言B.   数学方面?

如果两种语言都是Turing complete,则可以将其中一种语言翻译成另一种语言。

至于你的PHP到C的假设,有像HipHop这样的“源到源”编译器,但这不是常见的情况。大多数动态类型语言都编译为字节代码并在虚拟机上运行。

对于C,编译器将其转换为目标处理器的汇编语言。

如果您想了解更多信息,可以阅读有关编译器设计,抽象语法树和语言语义的信息。如果你是新手,那么立即接受它是很多的,所以Stack Overflow真的不是开始这个​​主题的最好的地方。