【问题标题】:What type of parser is needed for this grammar?这个语法需要什么类型的解析器?
【发布时间】:2023-03-24 23:23:02
【问题描述】:

我有一个语法,除了我不相信语法是 LL(1) 之外,我不知道我需要什么类型的解析器来解析它。我在想我需要一个带有回溯或某种 LL(*) 的解析器。我想出的语法(可能需要重写)是:

S: Rules
Rules: Rule | Rule Rules
Rule: id '=' Ids
Ids: id | Ids id

我尝试生成的语言如下所示:

abc = def g hi jk lm
xy = aaa bbb ccc ddd eee fff jjj kkk
foo = bar ha ha 

零个或多个包含左标识符后跟等号后跟一个或多个标识符的规则。我认为编写解析器时会遇到问题的部分是语法允许规则中包含任意数量的 id,并且判断新规则何时开始的唯一方法是找到 id =,这需要回溯。

对于手写解析器,有谁知道这种语法的分类和最佳解析方法?

【问题讨论】:

  • 最后一条规则不需要在 RHS 上的“Ids”之前或之后包含一个额外的“id”吗?

标签: parsing grammar


【解决方案1】:

生成标识符后跟等号后跟有限标识符序列的语法是regular。这意味着可以使用 DFA 或正则表达式解析语言中的字符串。不需要花哨的非确定性或 LL(*) 解析器。

要看到语言是规则的,让 Id = U {a : a ∈ Γ},其中 Γ ⊂ Σ 是标识符中可能出现的一组符号。您尝试生成的语言由正则表达式表示

  • Id+ =( Id+)*Id+

设置Γ = {a, b, ..., z},正则表达式语言中的字符串示例有:

  • 看 = 我用的是普通语言
  • 嘿 = 这意味着我可以被 dfa 识别
  • cool = 甚至是正则表达式

无需使用强大的解析技术来解析您的语言。这是使用正则表达式或 DFA 进行解析既合适又最佳的一种情况。

编辑:

调用上面的正则表达式R。要解析 R*,请生成识别 R* 语言的 DFA。为此,使用可从 Kleene 定理获得的算法生成识别 R* 语言的 NFA。然后使用子集构造将 NFA 转换为 DFA。生成的 DFA 将识别 R* 中的所有字符串。给定在您的实现语言中构建的 DFA 的表示,所需的操作 - 例如,

  • 将最后解析的标识符添加到正在解析的当前声明语句的右侧
  • 将最后解析的声明语句添加到已解析的声明列表中,并使用最后解析的标识符开始解析新的声明语句

可以编码为 DFA 的状态。实际上,对于这种简单的语言,可能不需要使用 Kleene 定理和子集构造。也就是说,您可能只需编写具有上述两个操作的解析器,而无需实现自动机。给定更复杂的常规语言(例如,编程语言的词法结构),转换将是最佳选择。

【讨论】:

  • 很好的回应,但是,我如何在递归下降解析器中确定一个特定规则何时结束并开始一个新规则,而不需要任何花哨的方法。因为它不仅必须生成一个标识符后跟一个等号,然后是一个有限的标识符序列,它还必须允许这些标识符的有限集。我猜它必须是 LL(3)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-24
  • 1970-01-01
  • 2015-12-23
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
相关资源
最近更新 更多