我有一个antlr4语法,专门用于嵌入到文本模板中的特定于域的语言.
有两种模式:
示例语法部分:
template
: '{' templateBody '}'
;
templateBody
: templateChunk*
;
templateChunk
: code # codeChunk // dsl code, ignore whitespace
| text # textChunk // any text, preserve whitespace
;
Run Code Online (Sandbox Code Playgroud)
规则code可以包含对template规则的嵌套引用.因此解析器必须支持嵌套空白/非空白部分.
也许lexer模式可以帮助 - 有一些缺点:
然而,最有希望的方法似乎是操纵隐藏的渠道.
我的问题:是否有最佳实践来满足这些要求?是否有一个示例语法,已经解决了类似的问题?
附录:
其余的语法可能如下所示:
code
: '@' function
;
function
: Identifier '(' argument ')'
;
argument
: function
| template
;
text
: Whitespace+
| Identifier
| .+
;
Identifier
: LETTER (LETTER|DIGIT)*
;
Whitespace
: [ \t\n\r] -> channel(HIDDEN)
;
fragment LETTER
: [a-zA-Z]
;
fragment DIGIT
: [0-9]
;
Run Code Online (Sandbox Code Playgroud)
在这个例子中code有一个虚拟实现,指出它可以包含嵌套的代码/模板部分.其实code应该支持
这就是我最后解决问题的方法:
想法是在解析器规则中启用/禁用空格:
templateBody : {enableWs();} templateChunk* {disableWs();};
Run Code Online (Sandbox Code Playgroud)
因此,我们必须定义enableWs并disableWs在我们的解析器基类:
public void enableWs() {
if (_input instanceof MultiChannelTokenStream) {
((MultiChannelTokenStream) _input).enable(HIDDEN);
}
}
public void disableWs() {
if (_input instanceof MultiChannelTokenStream) {
((MultiChannelTokenStream) _input).disable(HIDDEN);
}
}
Run Code Online (Sandbox Code Playgroud)
现在这是什么MultiChannelTokenStream?
CommonTokenStream一个只能从一个通道读取的令牌流.MultiChannelTokenStream是从已启用的通道读取的令牌流.为了实现,我采用了CommonTokenStream的源代码并将每个引用替换为channelby channels(等式比较得到包含比较)上面的语法示例实现可以在antlr4multichannel找到
| 归档时间: |
|
| 查看次数: |
2465 次 |
| 最近记录: |