我有一个组合语法,需要提供两个标识符词法分析器规则。 两个标识符可以同时使用。在语法上,Identifier1在Identifer2之前。
第一个标识符是静态的,而第二个标识符规则根据某个标志而改变(使用谓词)。
我希望第二个标识符在解析器规则中匹配。但是由于这两个标识符可能与某些常用输入匹配,因此它不会属于identifer2。
我创建了小语法以使其易于理解。语法为:
address => 'required'
如果我尝试将identifer2规则匹配为:
@lexer::members
{
private boolean flag;
public void setFlag(boolean flag)
{
this.flag = flag;
}
}
identifier1 :
ID1
;
identifier2 :
ID2
;
ID1 : (CHARS) *;
ID2 : (CHARS | ({flag}? '_'))* ;
fragment CHARS
:
('a' .. 'z')
;
它显示错误: 第1:0行在“ abcabde”处缺少ID2
答案 0 :(得分:1)
ID1 : (CHARS) *;
ID2 : (CHARS | ({flag}? '_'))* ;
对于ANTLR,这两个规则意味着:
ID1
_
和flag == true
,则为ID2
请注意,如果flag == false
,ID2
将永远不会被匹配。
Lexer遵循的两个基本规则是:
我相信您的核心问题是误解词法分析器和解析器之间的区别以及它们的用法。您应该问自己的问题是:何时应将'abcabde'与ID1
匹配,何时与ID2
匹配?
ID1
-那么您的语法是正确的。ID2
-然后您应该切换两个规则-但请注意,在这种情况下,ID1
将永远不匹配。flag
-然后您需要根据逻辑修改谓词,仅切换下划线是不够的。