0

我的任务是解析(和转换)一种计算机语言的代码,它的规则有点奇怪,至少我是这样看的。准确地说,编译器将新行(以及分号)视为语句分隔符,但除此之外(例如在语句内部),它会将它们视为间隔符(空格)。

例如,这段代码:

try
    local x = 5 / 0
catch (i)
    print(i + "\n")

证明等价于:

try local x = 5 / 0 catch (i) print(i + "\n")

我不知道如何在 EBNF 中,或者特别是在 Lark EBNF 方言中表达这样的规则。我的意思是一种明智的方式。我可能可以在所有语句中定义所有可能的换行位置,但这会很麻烦且容易出错。

我希望找到一种根据上下文处理换行符的方法。有没有一种经过验证的方法,最好是在 Python/Lark 域中?如果我必须为此修改解析器,那么我应该从哪里开始呢?

或者,如果我特别误解了这种语言或机器语言解析中的某些内容,或者我对问题的陈述是错误的,我也很乐意接受教育。

(正如您可能猜到的那样,所讨论的语言具有经过充分验证的实现,但没有正式定义的语法。此外,它是 Squirrel,尽管它很重要。)

4

1 回答 1

1

“规范”中的相关引用是这样的:

松鼠程序是一个简单的语句序列。:

stats := stat [';'|'\n'] stats

[...]语句可以用新行或';'分隔 (或使用关键字casedefaultif 在 switch/case 语句中),如果语句后跟“}”,则不需要这两个符号。

这些是相对复杂的规则,如果换行符也可以在其他任何地方忽略,它们总体上不是上下文无关的。但是请注意,在我的理解中,文本暗示;\n在其他情况均不适用时是必需的。那将使您的示例非法。这可能意味着所写的 BNF 是正确的,例如两者都是正确的,;并且\n在任何地方都是可选的。在这种情况下,您可以(对于云雀)只需发表一个%ignore "\n"声明,它应该可以正常工作。

另外,如果你既忽略 又在规则中使用它,Lark 也不应该抱怨\n:在有用的地方,它会在规则中匹配它,否则它会忽略它。但是请注意,如果您使用包含\n(例如WS/\s/)的终端,这会中断。只是\n作为一个额外的案例。

(对于未来:如果您在gitter上询问或至少在此处放置指向 SO 的链接,您可能会得到更快的回答。)

于 2021-05-29T00:22:50.923 回答