用ANTLR匹配任意文本(包括符号和空格)



如何匹配ANTLRv4中的任何文本?我指的是文本,在语法写作的时候是未知的?

我的语法如下:

grammar Anytext;
line :
    comment;
comment : '#' anytext;
anytext: ANY*;
WS : [ trn]+;
ANY : .;

我的代码如下:

    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
输出:

line 1:1 extraneous input ' ' expecting {<EOF>, ANY}
(comment # (anytext   T h i s _ i s _ a _ c o m m e n t))

如果我改变ANY规则

ANY : [ trn.];

它不再识别任何符号。

UPDATE1

结尾没有结束行字符

更新2

所以,我理解,这是不可能匹配任何文本与lexer,因为lexer不能允许多个类。如果我为任何符号定义词法分析器规则,它要么隐藏所有其他规则,要么不起作用。

但问题依然存在。

如何在解析器级别匹配所有符号?

假设我有表格形状的数据,我不想处理一些字段而忽略其他字段。如果我有anytext规则,我会写

infoline :
    ( codepoint WS 'field1' WS field1Value ) |
    ( codepoint WS 'field2' WS field2Value ) |
    ( codepoint WS anytext );

这里我解析行,如果第二列包含field1field2值,否则忽略行。

如何实现这个方法?

重要的是要记住,ANTLR会在解析器看到第一个标记之前将完整的输入分解为多个标记(至少它是这样做的)。您的词法分析器语法如下所示。

T__0 : '#'; // implicit token created due to the use of '#' in parser rule comment
WS : [ trn]+;
ANY : .;
对于您的输入,令牌如下:
  1. # (type T__0)
  2. [space] (type WS)
  3. T (type ANY)
  4. h (type ANY)
  5. i (type ANY)
  6. s (type ANY)
  7. _ (type ANY)
  8. i (type ANY)
  9. s (type ANY)
  10. _ (type ANY)
  11. a (type ANY)
  12. _ (type ANY)
  13. c (type ANY)
  14. o (type ANY)
  15. m (type ANY)
  16. m (type ANY)
  17. e (type ANY)
  18. n (type ANY)
  19. t (type ANY)

当前语法解析失败,因为comment规则中不允许WS标记。如果您使用this:

,它将解析这个输入(但在扩展语法时可能会遇到问题):
// remember that '#' is its own token
anytext: (ANY | WS | '#')*;

您可以做的是将comment更改为词法分析器规则,该规则使用#字符以及后面的内容(在本例中,直到行尾):

grammar Anytext;
line : COMMENT;
COMMENT : '#' ~[rn]*;
WS : [ trn]+;
ANY : .;

对行注释使用以下规则:

LINE_COMMENT
    :   '#' ~('n'|'r')* 'r'? 'n' {$channel=HIDDEN;}
    ;

它匹配'#'和任何符号,直到它到达行尾(unix/windows换行)。

由280Z28编辑:这里是完全相同的规则在ANTLR 4语法:

LINE_COMMENT
    :   '#' ~[rn]* 'r'? 'n' -> channel(HIDDEN)
    ;

相关内容

  • 没有找到相关文章

最新更新