首页 > 解决方案 > 使用 Pest.rs,如果 PUSH 是可选的,如何避免“在空堆栈上调用 peek”?

问题描述

Pest.rs 具有推送和窥视堆栈的能力。当用户给出分隔符时,这很有用,例如在 Perl 和 PostgreSQL 中找到的自定义引用(双美元语法)。如果项目可能不在堆栈上,我该怎么做。例如,Exim 配置文件指出,

也可以使用换行符和其他控制字符(代码值小于 32 的字符,加上 DEL)作为列表中的分隔符。此类分隔符必须在处理列表时按字面意思提供。对于字符串扩展的选项,您可以使用正常的转义序列编写分隔符。这将在字符串被解释为列表之前由扩展器处理。例如,如果通过查找生成以换行符分隔的域列表,则可以通过如下行直接处理它:

domains = <\n ${lookup mysql{.....}}

您可以在此处看到<\n覆盖默认分隔符的标记:是可选的。你可以看到这里的语法本质上是,

list_sep        = ${ "<" ~ (!WHITE_SPACE ~ ANY) }
list            = {
  list_type
  ~ key
  ~ "="
  ~ PUSH(list_sep)?
  ~ !(PEEK ~ ANY)+
  ~ (PEEK ~ !(PEEK ~ ANY))*
}

但是当我跑步时,我得到了,

peek 在空堆栈上被调用

无论如何,是否可以使用 PEG 提供此操作,以便将列表作为字符串呈现给用户,但作为元素标记的实际列表?

标签: parsingrustgrammarpegpest

解决方案


我开始做的一种方法是确保PUSH总是发生。甚至似乎一个可选的PUSH应该是编译器错误,

而不是

~ PUSH(list_sep)?

做这个,

~ PUSH(list_sep?)

推荐阅读