Suz*_*ioc 9 java regex antlr lexer antlr4
如何匹配ANTLRv4中的任何文本?我的意思是文字,这在语法写作时是未知的?
我的语法如下:
grammar Anytext;
line :
comment;
comment : '#' anytext;
anytext: ANY*;
WS : [ \t\r\n]+;
ANY : .;
Run Code Online (Sandbox Code Playgroud)
我的代码如下:
String line = "# This_is_a_comment";
ANTLRInputStream input = new ANTLRInputStream(line);
AnytextLexer lexer = new AnytextLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
AnytextParser parser = new AnytextParser(tokens);
ParseTree tree = parser.comment();
System.out.println(tree.toStringTree(parser)); // print LISP-style tree
Run Code Online (Sandbox Code Playgroud)
输出如下:
line 1:1 extraneous input ' ' expecting {<EOF>, ANY}
(comment # (anytext T h i s _ i s _ a _ c o m m e n t))
Run Code Online (Sandbox Code Playgroud)
如果我改变ANY
规则
ANY : [ \t\r\n.];
Run Code Online (Sandbox Code Playgroud)
它根本不再识别任何符号.
UPDATE1
我最后没有终点字符.
更新2
因此,我理解,由于词法分析器不允许多个类,所以不可能将任何文本与词法分析器匹配.如果我为任何符号定义词法分析器规则,它将隐藏所有其他规则或不起作用.
但问题仍然存在.
如何在解析器级别匹配所有符号呢?
假设我有表格数据,我不想处理某些字段而忽略其他字段.如果我有anytext
统治权,我会写
infoline :
( codepoint WS 'field1' WS field1Value ) |
( codepoint WS 'field2' WS field2Value ) |
( codepoint WS anytext );
Run Code Online (Sandbox Code Playgroud)
这里我解析行,如果第二列包含field1
和field2
值,否则忽略行.
如何实现这种方法?
重要的是要记住,在解析器看到第一个令牌之前,ANTLR会将您的完整输入分解为令牌(至少它的行为方式如此).您的词法分析器语法如下所示.
T__0 : '#'; // implicit token created due to the use of '#' in parser rule comment
WS : [ \t\r\n]+;
ANY : .;
Run Code Online (Sandbox Code Playgroud)
对于您的输入,令牌如下:
#
(类型T__0
)WS
)T
(类型ANY
)h
(类型ANY
)i
(类型ANY
)s
(类型ANY
)_
(类型ANY
)i
(类型ANY
)s
(类型ANY
)_
(类型ANY
)a
(类型ANY
)_
(类型ANY
)c
(类型ANY
)o
(类型ANY
)m
(类型ANY
)m
(类型ANY
)e
(类型ANY
)n
(类型ANY
)t
(类型ANY
)您当前的语法无法解析,因为规则中WS
不允许使用令牌comment
.如果你使用它,它会解析这个输入(但是当你扩展你的语法时可能会遇到问题):
// remember that '#' is its own token
anytext: (ANY | WS | '#')*;
Run Code Online (Sandbox Code Playgroud)
您可以做的是更改comment
为词法分析器规则,它会消耗该#
字符以及后面的内容(在这种情况下,到行尾):
grammar Anytext;
line : COMMENT;
COMMENT : '#' ~[\r\n]*;
WS : [ \t\r\n]+;
ANY : .;
Run Code Online (Sandbox Code Playgroud)
对行注释使用以下规则:
LINE_COMMENT
: '#' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
;
Run Code Online (Sandbox Code Playgroud)
它匹配“#”和任何符号,直到到达行尾(unix/windows 换行符)。
280Z28 编辑:这里是 ANTLR 4 语法中完全相同的规则:
LINE_COMMENT
: '#' ~[\r\n]* '\r'? '\n' -> channel(HIDDEN)
;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5013 次 |
最近记录: |