【问题标题】:How to test grammar changes in yacc/lalr(1) for backwards compatibilitiy?如何测试 yacc/lalr(1) 中的语法更改以实现向后兼容性?
【发布时间】:2023-03-29 04:30:02
【问题描述】:

我们的脚本语言已经在使用,我们正在通过添加新功能等对其进行改进。

我的问题是;测试我们的 grammer(不是最终应用)的向后兼容性的最佳方法是什么?有谁知道为我们制作它的工具或方法吗?

最好的问候

【问题讨论】:

  • 您需要有通过旧语法的测试文件并针对新语法运行它们。
  • @EJP 你能再解释一下吗,你的意思是什么?我知道必须将旧语法与新语法进行比较。 YACC 有测试文件的功能吗?
  • 放下它。究竟有什么好解释的?您应该已经有通过原始版本的测试。您所要做的就是针对新版本运行它们。如果您没有这些测试已经太晚了:您需要停止,构建这些测试,针对旧版本运行它们,冲洗并重复直到它们通过,然后针对新版本再次运行它们。当然这一切都是显而易见的吗?
  • @EJP 这是一门庞大的语言,因此我们无法测试所有可能性。从理论上讲,必须可以测试语法,而不是最终产品!我们已经知道用我们所做的测试代码(用我们的语言)来测试它。但这不是我想做的。
  • 那你要求的是不可能的。如果您还没有对以前的版本进行足够详尽的测试,您将不得不 (a) 构建它们,(b) 自己分析您的语法更改是否不兼容,或者 (c) 从您的用户。

标签: parsing yacc parser-generator lalr


【解决方案1】:

测试一种语法是否接受与另一种相同的语言,或者接受更大的语言,即使不是不可能,也很困难。

作为工程师,我们经常被要求做不可能的事情。我们所做的是放宽要求,直到我们得到某种有用的答案。放宽要求的一种方法是允许工具在某些情况下说“不知道”。

我的公司基于解析器生成器构建解析器。我们经常处理庞大的语法(数千条规则)。我们一直在研究的机制之一是检测语法是否有歧义。这在理论上是不可能的,但不会改变我们获得答案的兴趣。

我们正在开发一种可以在很多情况下回答这个问题的工具。实际上,它的作用是询问任何非终结符是否模棱两可;应用于根语法规则,这直接询问语法是否有歧义。在所有非终结符上尝试它的原因是它们中的许多生成的子语言比完整语言更小,从而可以对其进行分析。它通过使用语法规则对非终结符的扩展进行广度优先搜索来确定这一点。在此搜索期间会发生几件事之一:

  • 非终结符被证明是明确的
  • 它被证明是模棱两可的,这意味着主要的语法规则是模棱两可的
  • 搜索已用完我们愿意花费的时间。

通过记录搜索结果,并对所有语法规则进行多次迭代(使用称为“迭代深化”的搜索技术),我们通常可以发现歧义,和/或证明部分语法没有歧义。 (缓存终结符/非终结符 X 是否模棱两可的事实允许检查传递使用 X 的其他非终结符 Y,以有效地“更快”或“更深入”地搜索;这是国际象棋程序中转置表的旧技巧)。这个答案并不完美,但是当它识别出歧义时,确实有一个,而当它声称没有一个时,就没有一个。 这是一个很大的帮助。

在我看来,相同类型的搜索应该适用于询问一种语法是否接受另一种语法的超集,假设语法非常相似(例如,您通过“稍微”修改另一个语法)。 如果该非终结符是其孪生体的超集,则搜索必须检查语言共享的每个非终结符。同样,您得到的任何答案都不是完美的,但在提供兼容性方面可能会有很长的路要走。

正如@EJP 所指出的,我们知道如何做到这一点的唯一其他方法是运行大量的综合测试。

【讨论】:

  • @YusufRamazanKaragöz:你需要帮助吗?
  • 我认为那一刻要做的工作太多了。你的回答很有帮助。我将使用我们的旧测试方法。再次感谢您。
猜你喜欢
  • 1970-01-01
  • 2011-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-25
相关资源
最近更新 更多