c - 乱序解析 C 系列语言

标签 c parsing compiler-construction programming-languages

C 严格按顺序解析,即所有内容都必须在使用前声明;特别是,类型必须在这些类型的变量之前声明。这是有道理的,因为如果您不知道类型的名称是什么,什么不是,例如,语法将是模棱两可的。 a * b 取决于 a 是否命名了一个类型。

另一方面,某些 C 系列语言具有放宽此限制的理想属性(从而消除了头文件的手动杂耍)。我正在为 C 超集语言编写一个解析器,它的目的同样是放宽该限制,所以现在我需要弄清楚如何去做。

我想到的一种方法是进行两次传递。第一步遍历所有内容,利用顶层的所有内容都必须是声明而不是语句这一事实,并选取所有类型。在这个阶段,函数体没有被检查,只是作为由匹配的大括号分隔的标记流被拾取。第二遍解析函数体。函数内的局部声明必须按顺序排列,但这并不是真正的问题。

该方法中是否有任何我没有想到的绊脚石?

C++、Java、C# 等的编译器通常如何处理那些不需要按顺序声明的语言部分?

最佳答案

您不必在解析时进行名称解析。首先,如果您正在设计一种“类 C”语言(与新的 C 实现相对),您可以定义语法,以便声明、表达式、方法等在语法中都是明确的。然后解析顺序无关紧要。 (这也可以通过以结构化方式将预处理器集成到语言中来解决预处理器问题)。

如果您坚持使用类似 C 的语法,您可以使用容忍歧义的解析器,例如,是 happy to process "x*y;"并将其同时作为表达式和声明保存,直到它获得更多数据。在极端情况下,只需将其视为基于约束的解决方案。 C 和 C++ 坚持首先了解定义,因为最初编译器的内存空间非常有限,您不能只保留所有内容;这不再是真的。您不必在解析时坚持知道答案。

我们在 DMS Software Reengineering Toolkit 中为此使用了 GLR 解析器,非常高兴能够很好地解析 C 和 C++11。我们在解析之后进行名称解析;这将解析和名称解析隔离开来,使前端更简洁、更易于管理。

关于c - 乱序解析 C 系列语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14710118/

相关文章:

c - 如何将流中的字符添加到节点中?

java - 当我执行插入查询 RDF4J 时如何获取 UpdateExpr

c++ - 这段代码的目的是什么?它是在计算位数吗?

c - 在 C 中解析带引号的字符串

php - 从 PHP 解析 JSON

compiler-construction - 是否可以将Scala程序编译为可在任何JVM上运行,而无需在给定机器上安装Scala?

PHP 到 Ruby 编译器

c++ - 在 Fedora 14 上编译 C++ 程序时出现编译错误

iphone - Obj C 或 C 的三次样条类?

c - gcc 中的 -ffreestanding 选项是什么?