在Scala 3中(如果有关系的话,现在是3.1.3),我正在编写一个需要一些规则/语法处理的解析器,我想编写一个宏,它允许我为一个非终端定义备选程序,并定义非终端,以便它可以在其他规则中使用。现在所有的东西都是用非终端( Strings )和终端( Chars )编写的,所以as的元组语法的一组规则可能是:
new Grammar() {
val rules = Set(
Rule("tuple", List('(', "as", ')')),
Rule("as", List('a', "more")),
Rule("as", Nil),
Rule("more", List(',', "as")),
Rule("more", Nil),
)相反,我想做的是使用一些宏魔法,使其更像:
new Grammar() {
rule(tuple, List('(', as, ')')
rule(as, List('a', more), Nil)
rule(more, List(',', as), Nil)
}其中,我可以使用标识符而不是对非终端使用String,在编译时,rule宏将执行类似于将第二个宏转换为
new Grammar() {
val rules = mutable.Set()
val tuple = NonTerminal("tuple")
val as = NonTerminal("as")
val more = NonTerminal("more")
rules.add(Rule(tuple, List('(', as, ')')))
rules.add(Rule(as, List('a', more)))
rules.add(Rule(as, Nil))
rules.add(Rule(more, List(',', as)))
rules.add(Rule(more, Nil)
}在Scala 3宏的当前状态下,这种情况是可能的吗?还是宏不可能将尚未定义的标识符作为参数并为其提供定义?
发布于 2022-08-29 10:53:22
不,传递给宏的参数必须是正确的Scala代码。
您可以为非终端(通过使用动态)设置一个“上帝前缀”:
new Grammar() {
rule(?.tuple, List('(', ?.as, ')')
rule(?.as, List('a', ?.more), Nil)
rule(?.more, List(',', ?.as), Nil)
}但我不确定这是不是比Strings好。
https://stackoverflow.com/questions/73523127
复制相似问题