gpt4 book ai didi

java - ANTLR/语法问题 : calculator language

转载 作者:行者123 更新时间:2023-11-29 06:15:44 25 4
gpt4 key购买 nike

我正在尝试为个人项目创建 boolean 表达式语言/语法。用户将能够使用类似 Java 的语法编写字符串,并提供变量,这些变量将在稍后初始化变量时进行评估。雨例如,用户可能输入字符串

@FOO+7 > 4*(5+@BAR);

稍后,当变量 FOO 被初始化并等于 6,并且 BAR 等于 1 时,表达式的计算结果为 13>24,因此返回 false。

我正在使用 ANTLRworks 生成语法,虽然它看起来不错,但它不能正确解释负号。 ANTLRworks 中的输入(出于某种原因)已更改:“(8-3)>6”被读作“(8>6”(由于缺少右括号而无法运行)。我还没有实现变量查找尚未完成,但这里是目前为止仅用于整数的语法:

grammar BooleanCalculator;

@header {
package test;
}

prog : rule+
;

rule : boolean_expr ';' NEWLINE {System.out.println($boolean_expr.b);}
| NEWLINE
;

boolean_expr returns [boolean b]
: v1=num_statement
('<' v2=num_statement {$b = $v1.d < $v2.d;}
|'<=' v2=num_statement {$b = $v1.d <= $v2.d;}
|'=' v2=num_statement {$b = $v1.d == $v2.d;}
|'!=' v2=num_statement {$b = !($v1.d == $v2.d);}
|'>=' v2=num_statement {$b = $v1.d >= $v2.d;}
|'>' v2=num_statement {$b = $v1.d > $v2.d;})
;

num_statement returns [double d]
: v1=mult_statement {$d = $v1.d;}
('+' v2=mult_statement {$d += $v2.d;}
|'-' v2=mult_statement {$d -= $v2.d;})* //HERE IS THE OFFENDING LINE
;

mult_statement returns [double d]
: v1=var {$d = $v1.d;}
('*' v2=var {$d *= $v2.d;}
|'/' v2=var {$d /= $v2.d;}
|'%' v2=var {$d = $d/100*$v2.d;})*
;

var returns [double d]
: NUMBER {$d = Double.parseDouble($NUMBER.text);}
| '(' v1=num_statement ')' {$d = $v1.d;}
;

NUMBER : '0'..'9'+
;

它对除“-”符号以外的所有内容均能正常工作。有谁知道解决这个问题的方法吗?

此外(我是 ANTLR 的新手):我的评估是否正确?或者我应该让语法定义结构并使用另一种方法来确定语句是否为真/假?

最佳答案

你的语法:

grammar BooleanCalculator;

prog
: rule+
;

rule
: boolean_expr {System.out.println($boolean_expr.b);}
;

boolean_expr returns [boolean b]
: v1=num_statement ( '<' v2=num_statement {$b = $v1.d < $v2.d;}
| '<=' v2=num_statement {$b = $v1.d <= $v2.d;}
| '=' v2=num_statement {$b = $v1.d == $v2.d;}
| '!=' v2=num_statement {$b = !($v1.d == $v2.d);}
| '>=' v2=num_statement {$b = $v1.d >= $v2.d;}
| '>' v2=num_statement {$b = $v1.d > $v2.d;} {System.out.println("v1=" + $v1.d + ", v2=" + $v2.d);}
)
;

num_statement returns [double d]
: v1=mult_statement {$d = $v1.d;} ( '+' v2=mult_statement {$d += $v2.d;}
| '-' v2=mult_statement {$d -= $v2.d;}
)*
;

mult_statement returns [double d]
: v1=var {$d = $v1.d;} ( '*' v2=var {$d *= $v2.d;}
| '/' v2=var {$d /= $v2.d;}
| '%' v2=var {$d = $d/100*$v2.d;}
)*
;

var returns [double d]
: NUMBER {$d = Double.parseDouble($NUMBER.text);}
| '(' v1=num_statement ')' {$d = $v1.d;}
;

NUMBER
: '0'..'9'+
;

(请注意,我没有更改任何其他内容,只是稍微重新格式化,并添加了一个额外的 println 用于调试!)

产生了以下输出:

$ java -cp antlr-3.2.jar org.antlr.Tool BooleanCalculator.g 
$ javac -cp antlr-3.2.jar *.java
$ java -cp .:antlr-3.2.jar Main

v1=5.0, v2=6.0
false

使用测试类:

import org.antlr.runtime.*;

public class Main {
public static void main(String[] args) throws Exception {
ANTLRStringStream in = new ANTLRStringStream("(8-3)>6");
BooleanCalculatorLexer lexer = new BooleanCalculatorLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
BooleanCalculatorParser parser = new BooleanCalculatorParser(tokens);
parser.prog();
}
}

所以,一切似乎都很顺利。

几点说明:

  • 您正在使用 ==!= 比较 double。请注意:舍入错误会导致意外行为(从用户的角度来看...);
  • 在语法操作中使用模运算符可以通过使用反斜杠将其转义来完成:\%

关于java - ANTLR/语法问题 : calculator language,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5154628/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com