假设我在ANTLR 4中定义了一个非常简单的语法:
input : String Separator String ;
String : 'a'..'z' ;
Separator : ',' ;
对于这个语法,分隔符是固定的;它总是一个逗号。有没有办法让分隔符变量?也就是说,我想使用输入参数定义分隔符,该参数由调用lexer-parser的代码设置。我可以这样定义一个getter和setter:
@lexer::members
{
String sep = ",";
public void setSep(String sep)
{
this.sep = sep;
}
private String getSep()
{
return sep;
}
}
但是如何在词法分析器规则中更改分隔符的值?这很接近,但错了:
Separator : ',' { setText(getSep()); } ;
答案 0 :(得分:1)
在查看其他一些问题之后,我决定尝试使用语义谓词来解决这个问题。这是我的完整解决方案:
grammar InputCombinedGrammar;
@parser::members
{
String sep = ",";
public void setSep(String sep)
{
this.sep = sep;
}
private String getSep()
{
return sep;
}
}
input : String { getSep().equals(_input.LT(1).getText()) }? Separator String EOF ;
String : 'a'..'z' ;
Separator : . ;
需要注意的两件事:
此解决方案信任语义谓词仅使用正确的分隔符。我对这个解决方案很满意,但我想看到别人。
答案 1 :(得分:1)
我会在词法分析器中处理它:
@lexer::members {
...
}
input : String Separator String EOF ;
Separator : { sep.equals(_input.LA(1).getText()) }? . ;
String : 'a'..'z' ;
如果您在解析器中执行此操作,那么在 Separator : . ;
之后定义的所有规则永远不能是单个字符,因为它会被Separator
规则捕获。