语义谓词失败但不转到下一个
Semantic predicates fail but don't go to the next one
我尝试使用 ANTLR4 来识别像 <1..100>
这样的范围符号,这是我的尝试:
@parser::members {
def evalRange(self, minnum, maxnum, num):
if minnum <= num <= maxnum:
return True
return False
}
range_1_100 : INT { self.evalRange(1, 100, $INT.int) }? ;
但它不适用于多个范围,例如:
some_rule : range_1_100 | range_200_300 ;
当我输入一个数字(200
)时,它就停在第一条规则:
200
line 3:0 rule range_1_100 failed predicate: { self.evalRange(1, 100, $INT.int) }?
(top (range_1_100 200))
这和我想象的不一样。如何使令牌匹配下一条规则 (range_200_300
)?
以下是 the docs 的摘录(强调我的):
Predicates can appear anywhere within a parser rule just like actions can, but only those appearing on the left edge of alternatives can affect prediction (choosing between alternatives).
[...]
ANTLR's general decision-making strategy is to find all viable alternatives and then ignore the alternatives guarded with predicates that currently evaluate to false. (A viable alternative is one that matches the current input.) If more than one viable alternative remains, the parser chooses the alternative specified first in the decision.
这基本上意味着您的谓词 必须 是在预测阶段要考虑的交替中的第一个项目。
当然,您将无法使用 $INT
,因为此时尚未匹配,但您可以将其替换为 _input.LA(1)
之类的内容(先行一个token) - 确切的语法取决于你的语言目标。
附带说明一下,我建议您不要通过语法验证输入,在之后执行单独的验证过程更容易也更好 解析。让语法处理句法,而不是语义。
我尝试使用 ANTLR4 来识别像 <1..100>
这样的范围符号,这是我的尝试:
@parser::members {
def evalRange(self, minnum, maxnum, num):
if minnum <= num <= maxnum:
return True
return False
}
range_1_100 : INT { self.evalRange(1, 100, $INT.int) }? ;
但它不适用于多个范围,例如:
some_rule : range_1_100 | range_200_300 ;
当我输入一个数字(200
)时,它就停在第一条规则:
200
line 3:0 rule range_1_100 failed predicate: { self.evalRange(1, 100, $INT.int) }?
(top (range_1_100 200))
这和我想象的不一样。如何使令牌匹配下一条规则 (range_200_300
)?
以下是 the docs 的摘录(强调我的):
Predicates can appear anywhere within a parser rule just like actions can, but only those appearing on the left edge of alternatives can affect prediction (choosing between alternatives).
[...]
ANTLR's general decision-making strategy is to find all viable alternatives and then ignore the alternatives guarded with predicates that currently evaluate to false. (A viable alternative is one that matches the current input.) If more than one viable alternative remains, the parser chooses the alternative specified first in the decision.
这基本上意味着您的谓词 必须 是在预测阶段要考虑的交替中的第一个项目。
当然,您将无法使用 $INT
,因为此时尚未匹配,但您可以将其替换为 _input.LA(1)
之类的内容(先行一个token) - 确切的语法取决于你的语言目标。
附带说明一下,我建议您不要通过语法验证输入,在之后执行单独的验证过程更容易也更好 解析。让语法处理句法,而不是语义。