我可以使用antlr来解析部分数据吗?

时间:2012-11-04 14:34:05

标签: antlr

我正在尝试使用antlr来解析日志文件。因为我只对日志的部分内容感兴趣,所以我只想编写一个部分解析器来处理重要的部分。

例如: 我想解析这段:

[ 123 begin ]

所以我写了语法:

log :   
    '[' INT 'begin' ']'
    ;


INT : '0'..'9'+
    ;


NEWLINE
    : '\r'? '\n'
    ;

WS
    : (' '|'\t')+ {skip();}
    ;

但该段可能出现在一行的中间,例如:

 111 [ 123 begin ] 222

根据讨论: What is the wrong with the simple ANTLR grammar? 我知道为什么我的语法不能处理上述陈述。

我想知道,有没有办法让antlr忽略任何错误,并继续处理剩余的文本?

感谢您的任何建议! 利昂

1 个答案:

答案 0 :(得分:7)

由于在'['之外的某些情况下也可能会跳过[ 123 begin ],因此在词法分析器中无法处理此问题。您必须创建一个与要跳过的标记匹配的解析器规则(请参阅noise规则)。

如果其他词法分析规则都不匹配,您还需要创建匹配任何字符的直通规则(请参阅ANY规则)。

快速演示:

grammar T;

parse
    : ( log {System.out.println("log=" + $log.text);}
      | noise
      )*
      EOF
    ;

log : OBRACK INT BEGIN CBRACK
    ;

noise
    : ~OBRACK                  // any token except '['
    | OBRACK ~INT              // a '[' followed by any token except an INT
    | OBRACK INT ~BEGIN        // a '[', an INT and any token except an BEGIN
    | OBRACK INT BEGIN ~CBRACK // a '[', an INT, a BEGIN and any token except ']'
    ;

BEGIN   : 'begin';
OBRACK  : '[';
CBRACK  : ']';
INT     : '0'..'9'+;
NEWLINE : '\r'? '\n';
WS      : (' '|'\t')+ {skip();};
ANY     : .;