当前位置: 首页 > 知识库问答 >
问题:

Antlr4令牌存在扰乱解析

葛安和
2023-03-14
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;
$ 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中的数据,然后单击enter并单击Control+D。

在这方面的任何帮助都将非常感谢,一直在敲我的头在这一点上的键盘现在。

共有1个答案

章哲茂
2023-03-14

识别->的问题是主机名匹配任何字母、数字和破折号序列,其中包括50985-。由于该匹配项长于所匹配的数字(50985),所以主机名获胜。这显然不是你想要的。

解析日志行通常需要上下文敏感的扫描器,而标准的解析器生成器--更倾向于解析编程语言--并不总是理想的工具。例如,在这种情况下,主机名不能出现在识别它的上下文中,因此它甚至不应该出现在可能的令牌列表中。

当然,您可以定义一个由ip号和端口组成的令牌,用斜杠分隔,这样可以解决歧义,但是(在我看来)这将是次优的,因为您最终会重新扫描令牌来解析它。

 类似资料:
  • 我们如何才能让他们识别lexer规则?所有、和规则都可能与匹配。那么我在测试它的时候应该使用什么类型。 我的意思是: 一般来说,我想了解如何知道的类型?

  • 我正在为一种语言编写一个编译器,作为大学使用ANTLR4的项目。我使用Java编写了这个编译器,并采用了Visitor模式,当我到达测试阶段时,我注意到ANTLR忽略了我的部分代码,并生成了它不应该生成的错误。 语法: 以下是我的主要观点: 当我运行Main时,它显示: 第1行:0不匹配的输入'import'应为{(',INT,FLOAT,STRING,IDF} 我的语法有什么地方错了吗?如果没有

  • 我是一个Antlr4新手,有一个相对简单的语法问题。语法在末尾的底部给出。(这是一个语法片段,用于分析生物序列变体的描述)。 在下面的单元测试中,我试图解析字符串。 这里出了什么问题?我在哪里可以学习如何解决这个问题?

  • 我需要编写一个Java程序,使用,在给定一个源文件和一个方法的情况下,可以计算变量、运算符、标点符号和保留字的数量。 如何使用根据标记的类型对其计数?

  • 标准的TestCase之一是,lexer应该从中生成令牌流。不幸的是,由于ANTLR优先匹配较长的令牌,它生成令牌流,这将导致解析器引发错误。 是否可以先让ANTLR4 lexer尝试使用较短的令牌进行匹配?向添加lookahead-type规则并不是一个很好的解决方案,因为我需要考虑各种潜在的词法冲突(例如,被命名为,而不是,等等)。 编辑: 但这并不是一个真正的可扩展或可维护的解决方案,而且还

  • 如何检索找到的标记映射(例如),以便验证文本是否已正确映射到标记?