第一次发布海报,如果我违反规则,我最大的道歉。 我使用Antlr4创建了一个日志解析器,并且遇到了一些我不了解的问题。
我试图解析以下输入日志序列:
USA1-RR-SRX240-EDGE-01 created 10.20.30.40/50985->11.12.13.14/443
使用以下语法:
grammar Juniper;
WS : (' '|'\t')+ -> skip ;
NL : '\r'? '\n' -> skip ;
fragment DIGIT : '0'..'9' ;
NUMBER : DIGIT+ ;
IPADDRESS : NUMBER '.' NUMBER '.' NUMBER '.' NUMBER ;
SLASH : '/' -> skip ;
RIGHTARROW : '->' -> skip ;
CREATED: 'created' -> skip ;
HOSTNAME : [a-zA-Z0-9\-]+ ;
/* Input sample for rule: USA1-RR-SRX240-EDGE-01 created 10.20.30.40/50985->11.12.13.14/443 */
testcase : HOSTNAME WS CREATED WS IPADDRESS SLASH NUMBER RIGHTARROW IPADDRESS SLASH NUMBER NL;
它失败了,我不能为我的生活找出原因。我知道令牌识别错误与我为包含字符类中的破折号的HOSTNAME定义的令牌有关,但我不确定如何修复它。
$ antlr4 Juniper.g4 && javac Juniper*.java && grun Juniper testcase -tree
USA1-RR-SRX240-EDGE-01 created 10.20.30.40/50985->11.12.13.14/443
line 1:48 token recognition error at: '>'
line 1:30 mismatched input '10.20.30.40' expecting WS
(testcase SA1-RR-SRX240-EDGE-01 10.20.30.40 50985- 11.12.13.14 443)
请注意上面输出的第二行是我粘贴到grun然后按回车并按下控件+ D的数据。
对此我提供的任何帮助都会受到高度赞赏,现在我一直在敲打键盘。
答案 0 :(得分:0)
识别->
的问题是HOSTNAME匹配任何字母,数字和短划线,包括50985-
。由于该匹配比NUMBER匹配的时间长(50985
),因此HOSTNAME获胜。那显然不是你想要的。
解析日志行通常需要一个上下文相关的扫描程序,而标准的解析器生成器 - 更倾向于解析编程语言 - 并不总是理想的工具。在这种情况下,例如,HOSTNAME不能出现在识别它的上下文中,因此它甚至不应该在可能的令牌列表中。
当然,你可以定义一个令牌,它由一个用斜线分隔的ip号和端口组成,这可以解决歧义,但(在我看来)这将是次优的,因为你最终会重新扫描令牌解析它。