首页 文章

Antlr4浮点解析

提问于
浏览
0

我有以下antlr4代码:

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

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

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

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

并且不适用于 "5"

我究竟做错了什么?

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

1 回答

  • 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
      : .
      ;
    

相关问题