微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在语法中添加一点上下文?

如何解决如何在语法中添加一点上下文?

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

举个例子,这段代码

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,因为它很重要。)

解决方法

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

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

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

[...] 语句可以用新行或 ';' 分隔(或者如果在 switch/case 语句中,则用关键字 casedefault),两个符号都不是必需的如果语句后跟'}'。

这些是相对复杂的规则,如果换行符也可以在其他地方被忽略,那么它们总体上不是上下文无关的。但是请注意,根据我的理解,文本暗示 ;\n 在其他情况不适用时是必需的。那会使你的例子非法。这可能意味着所写的 BNF 是正确的,例如;\n 都是可选的。在这种情况下,您可以(对于百灵鸟)只需放置一个 %ignore "\n" 语句,它应该就可以正常工作。

此外,如果您都忽略 \n 并在规则中使用它,lark 不应该抱怨:如果有用,它将在规则中匹配它,否则它只会忽略它。但是请注意,如果您使用包含 \n(例如 WS/\s/)的终端,这会中断。只需将 \n 作为一个额外的案例。

(对于未来:如果您在 gitter 上询问或至少在那里放一个指向 SO 的链接,您可能会更快地获得对百灵鸟问题的答复。)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。