添加skip
到规则不符合我的预期.这是一对由逗号和空格分隔的标记的语法.我制作了一个用逗号标记的版本,另一个版本skip
没有:
grammar Commas;
COMMA: ', ';
COMMASKIP: ', ' -> skip;
DATA: ~[, \n]+;
withoutSkip: data COMMA data '\n';
withSkip: data COMMASKIP data '\n';
data: DATA;
Run Code Online (Sandbox Code Playgroud)
测试规则没有skip
按预期工作:
$ echo 'a, b' | grun Commas withoutSkip -tree
(withoutSkip (data a) , (data b) \n)
Run Code Online (Sandbox Code Playgroud)
随着skip
给我一个错误:
$ echo 'a, b' | grun Commas withSkip -tree
line 1:1 mismatched input ', ' expecting COMMASKIP
(withSkip (data a) , b \n)
Run Code Online (Sandbox Code Playgroud)
如果我注释掉COMMA
和withoutSkip
规则,我得到这个:
$ echo 'a, b' | grun Commas withSkip -tree
line 1:3 missing ', ' at 'b'
(withSkip (data a) <missing ', '> (data b) \n)
Run Code Online (Sandbox Code Playgroud)
我试图得到只有没有逗号的数据标记的输出,如下所示:
(withSkip (data a) (data b) \n)
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
skip
导致词法分析器丢弃令牌.因此,skip
ped lexer规则不能用于解析器规则.
另外,如果两个或多个规则匹配相同的输入,则首先定义的规则将从语法中稍后定义的规则中"赢",无论解析器是否尝试匹配语法中稍后定义的规则,第一条规则永远是"胜利".在您的情况下,COMMASKIP
永远不会创建规则,因为COMMA
匹配相同的输入.
尝试这样的事情:
语法逗号;
COMMA : ',' -> skip;
SPACE : (' '|'\n') -> skip;
DATA : ~[, \n]+;
data : DATA+;
Run Code Online (Sandbox Code Playgroud)
那么如何在不解析逗号树的情况下指定逗号的位置?您的代码将匹配a,b.
你不这样做,所以如果逗号很重要(即.a,,b
)无效,就不能从词法分析器中跳过它.
我认为在antlr3中你应该使用感叹号.
在ANTLR 4中,您无法从解析中创建AST.在新版本中,所有终端/规则都在一个解析树中.您可以使用自定义访问者和/或侦听器迭代此树.在此问答中可以找到如何执行此操作的演示:一旦语法完成,走ANTLR v4树的最佳方法是什么?
在您的情况下,语法将如下所示:
grammar X;
COMMA : ',';
SPACE : (' '|'\n') -> skip;
DATA : ~[, \n]+;
data : DATA (COMMA DATA)*;
Run Code Online (Sandbox Code Playgroud)
然后创建一个这样的监听器:
public class MyListener extends XBaseListener {
@Override
public void enterData(XParser.DataContext ctx) {
List dataList = ctx.DATA(); // not sure what type of list it returns...
// do something with `dataList`
}
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,它COMMA
并没有被移除,但在enterData(...)
你内部只是使用了DATA
令牌.
归档时间: |
|
查看次数: |
3257 次 |
最近记录: |