首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Antlr4浮点解析

Antlr4浮点解析
EN

Stack Overflow用户
提问于 2014-12-15 05:00:23
回答 1查看 1.6K关注 0票数 0

我有以下antlr4代码:

代码语言:javascript
复制
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时,它正确地工作。但它也适用于这些字符串:

代码语言:javascript
复制
"0001.2000."
"0001.2000.asfgheg"
".0001.2000.37"
"5.61345345ggdfhfjg"

"5"上不起作用

我做错了什么?

此外,为什么即使解析失败,antlr4也会尝试计算表达式?我得到了token recognition error,但是评估结果还是打印出来了。怎么让它失效?

EN

回答 1

Stack Overflow用户

发布于 2014-12-15 11:52:15

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

代码语言:javascript
复制
decnum
  : NUMBER
  ;

继续输入"5"。此输入与上面列出的任何规则不匹配,因为语法中没有任何规则包括输入字符"。当ANTLR 4到达此字符且没有规则匹配时,它将通过跳过该字符并继续下一个字符恢复。第一次发生这种情况时,ANTLR 4将从本质上看这个问题,以找到下一个令牌:5"

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

对于您提供的其他字符串,将使用类似的计算序列。例如,"0001.2000.asfgheg"匹配为:

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

在解析器中,上面的内容只显示为POINTNUMBERPOINT

如果您想将我前面提到的跳过的字符作为语法错误包含在解析树中,您可以通过在lexer中添加以下规则来实现这一点。此规则匹配任何单个字符,但前提是没有其他规则匹配,这正是错误恢复机制在不包括规则时所匹配的。此规则将将错误字符作为单个ErrorCharacter令牌传递给解析器。

代码语言:javascript
复制
ErrorCharacter
  : .
  ;
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27477631

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档