如何在语法中完成以下组合



我想设置一个规则,即我可以有一个以非保留字开头的表达式,但它可以包含一个可以包含保留字的路径。例如:

myFunc().select
table.select.select.myFunc().array[0].select
new.select.test

我的想法是使用这样一条规则:

exprWithoutReservedKeyword (DOT exprWithReservedKeyword)*

然而,这似乎是令人难以置信的重复,例如,如果expr规则有30个替代方案,例如:

expr:
OPEN_PAREN expr CLOSE_PAREN
| selectStatement
| ...

那么,我该如何实现这一点,我是否必须重写(即复制粘贴(整个表达式两次,然后再添加一次reservedKeyword规则?如果两者都是递归的,那么这两个规则之间难道不会有令人难以置信的模糊性竞争吗?什么是处理它的好方法?

或者,我需要基本上使每个子表达式都是非递归的,并在父表达式中处理它,例如:

expr:
exprWithoutReservedKeyword (DOT exprWithReservedKeyword)*
| expr
;

我想在expr规则的某个地方(可能隐藏在子规则中(,会有这样的东西:

path : IDENTIFIER
| path '.' IDENTIFIER

你会想把它改成

path : IDENTIFIER
| path '.' (IDENTIFIER | reserved_word)

其中reserved_word在某个地方被定义为保留字标记的连词,这可能是一个长列表。

在带有"的语言中;半保留的";单词,你会发现在其他上下文中,一些保留单词是可能的,但不是全部;要处理这些问题,您需要其他集合以及reserved_word。这可能会很乏味,但幸运的是,你只需要做一次。

注意,reserved_word必须是非终端,而不是令牌;如果它是一个代币,它将被无条件地认可,但你只希望它在这种特定的背景下被认可。

相关内容

  • 没有找到相关文章

最新更新