Antlr4浮点解析

时间:2014-12-15 05:00:24

标签: java antlr antlr4

我有以下antlr4代码:

decnum returns [double value] :
    NUMBER {$value = Double.parseDouble($NUMBER.text);}
    ;

POINT : '.';
INTNUMBER : ('0'..'9')+ ;
NUMBER : INTNUMBER (POINT INTNUMBER)?;

当我在System.out.println(parser.decnum().value);String s = 1.2时,它可以正常工作。但它也适用于这些字符串:

"0001.2000."
"0001.2000.asfgheg"
".0001.2000.37"
"5.61345345ggdfhfjg"

并且不适用于"5"

我做错了什么?

另外,为什么即使解析失败,antlr4也会尝试计算表达式?我得到了token recognition error,但无论如何都打印了评估结果。如何禁用它?

1 个答案:

答案 0 :(得分:3)

从最后一项开始:表达式正在评估解析是否成功,因为您将评估作为规则的一部分包含在内。使用ANTLR 4的推荐方法是允许它简单地构建一个解析树,然后在完成解析后使用监听器和/或访问者来执行所需的评估。例如,您的decnum规则应如下所示:

decnum
  : NUMBER
  ;

继续输入"5"。此输入与您在上面列出的任何规则都不匹配,因为语法中没有规则包含输入字符"。当ANTLR 4到达此角色并且没有规则匹配时,它将通过跳过角色并继续下一个角色来恢复。第一次发生这种情况时,ANTLR 4将主要查看此内容以查找下一个标记:5"

当ANTLR 4开始匹配5"时,它确定INTNUMBERNUMBER规则都与输入5匹配,这是最长匹配,因为没有规则匹配较长的序列5"。 ANTLR 4只能为每个令牌分配一个令牌类型,这是在任何解析规则看到令牌之前执行的。它不是将值INTNUMBERNUMBER都分配给5,而是根据规则在语法中出现的顺序确定此案例的令牌类型;即,ANTLR 4将5INTNUMBER令牌匹配,也是NUMBER令牌。最后,ANTLR 4跳过最后一个"字符的原因与跳过第一个字符的原因相同。

类似的评估序列用于您提供的其他字符串。例如,"0001.2000.asfgheg"匹配为:

  • ":忽略错误(不匹配)
  • .POINT
  • 0001.2000NUMBER
  • .POINT
  • a:忽略错误(不匹配)
  • s:忽略错误(不匹配)
  • f:忽略错误(不匹配)
  • g:忽略错误(不匹配)
  • h:忽略错误(不匹配)
  • e:忽略错误(不匹配)
  • g:忽略错误(不匹配)
  • ":忽略错误(不匹配)

对于解析器,上面显示为POINTNUMBERPOINT

如果要将上面提到的跳过的字符作为语法错误包含在解析树中,可以通过添加以下内容作为词法分析器中的最后一条规则来实现。此规则匹配任何单个字符,但仅当没有其他规则匹配时,这正是错误恢复机制在您不包含规则时匹配的内容。此规则将错误字符作为单个ErrorCharacter令牌传递给解析器。

ErrorCharacter
  : .
  ;