【问题标题】:Syntax analysis and syntax tree语法分析和语法树
【发布时间】:2011-11-20 21:33:04
【问题描述】:

我正在为一个学校班级实现一个编译器,但我在如何进行时遇到了一些问题。 已经进行了词法分析。对我来说,词法分析是我有一个函数,它返回标记对象并打印一些可以在词法分析期间检查的错误。

token包含id、string(如果当前id是string,如果不是null)、number(如果token是number,如果不是null)和token所在的行。

我想进行语法分析,但我不确定在此过程中是否必须生成语法树。我确信在生成中间代码时这将是必要的,但老师将决定权留给我们。

到此结束。老师想让我们明白,有必要吗? 如果真的有必要,构造语法树的最佳方法是什么? 我是否还遗漏了一些会在后期给我带来麻烦的东西?

【问题讨论】:

  • 嗯,没有复杂中间表示的一次性编译器当然是可能的。但它是否可行取决于语言和所需的功能。

标签: parsing compiler-construction lexical-analysis abstract-syntax-tree


【解决方案1】:

基本上,您的语法分析最终会成为某种形式的finite-state machine。这个过程的结果通常是一个 AST;如果你不将它的结果存储在某个地方,那么语法分析似乎有点毫无意义。

虽然有 many different well-known and established algorithms for creating the state tables and for implementing the actual processor,但您可能想开始像编译器一样思考并手动定义您的状态(这对于非常简单的语言是可行的):

  • 一开始,哪些令牌是可以接受的? (开始状态)
  • 每个标记将引导您进入另一个状态,并可能让您执行操作以将标记合并到抽象语法树中。 (状态转换)
  • 我建议将“文件结尾”视为标记器返回的特殊标记,以便您的语法分析不需要任何特殊代码来处理文件结尾(只是处理 EOF 标记的正常状态转换) .

请注意,除了使用表格之外,您还可以使用函数来表示您的状态。

您尝试实现的语言是什么?

【讨论】:

  • 我将文件结尾视为一个标记,但我决定在以后的阶段不需要它。结果,我创建了一个函数来运行词法分析器并返回一个令牌,直到我们到达文件末尾。我尝试实现的语言是类 c 语言。
  • 我的建议是保留 EOF 令牌,因为您的状态机将需要它以避免对 EOF 进行自定义检查。假设我们解析类似这样的内容:void A() { return 1; } - 在处理完} 之后,语法分析如何知道要切换到什么状态(“接受”,例如成功完成解析)?相信我,您不想到处添加if (IsEOF) 之类的代码 - 通过避免特殊情况来简化您的设计,并将其视为普通标记。
  • 我是这样做的,所以如果一个函数要求下一个令牌并且这个令牌为空,我将退出程序。
  • 您很快就会发现在 EOF/null 上退出是不合适的,因为您的解析器需要支持某种形式的递归(例如匹配 {},即使它们是嵌套的等),并且您很可能在堆栈上有多个状态,当达到 EOF 时需要“最终确定”。正如我所说,你引入的代码越不专业,你的代码就会变得越简单和干净。
  • 如果我们到达 EOF,尝试查找 } 的意义何在?
猜你喜欢
  • 2011-12-16
  • 2013-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多