ANTLR-允许不完整语法

ANTLR-允许不完整语法,antlr,antlr3,Antlr,Antlr3,我使用ANTLR解析数学表达式的字符串,并使用MathML标记它们 现在我有下面的语法。现在我有三个问题: 语法允许完整的表达式,如2*(3+4)。我想要 它还允许不完整的表达式,例如作为 完全是ANTLR的新手,我不知道如何做到这一点。 请给我指出正确的文件或举个例子 平方根规则sqrt在原子中的位置似乎 但我很确定它应该在指数中的某个地方 规则?还是应该 如果我想扩展这个语法来实际执行 计算,我可以重新使用它吗,还是必须复制粘贴 对于我的语法方面的任何其他评论或建议,我也非常感谢,因为我现在

我使用ANTLR解析数学表达式的字符串,并使用MathML标记它们

现在我有下面的语法。现在我有三个问题:

  • 语法允许完整的表达式,如
    2*(3+4)
    。我想要 它还允许不完整的表达式,例如作为 完全是ANTLR的新手,我不知道如何做到这一点。 请给我指出正确的文件或举个例子
  • 平方根规则
    sqrt
    在原子中的位置似乎 但我很确定它应该在
    指数中的某个地方
    规则?还是应该
  • 如果我想扩展这个语法来实际执行 计算,我可以重新使用它吗,还是必须复制粘贴
  • 对于我的语法方面的任何其他评论或建议,我也非常感谢,因为我现在使用ANTLR的总时间大约是四个小时

    grammar Expr;
    
    parse returns [String value]
        :   stat+ {$value = $stat.value;}
        ;
    
    stat returns [String value]
        :   exponent NEWLINE {$value = "<math>" + $exponent.value + "</math>";}
        |   NEWLINE
        ;
    
    exponent returns [String value]
        :   e=expr {$value = $e.value;}
            (   '^' e=expr {$value = "<msup><mrow>" + $value + "</mrow><mrow>" + $e.value + "</mrow></msup>";}
            )*
        ;
    
    expr returns [String value]
        :   e=multExpr {$value = $e.value;}
            (   '+' e=multExpr {$value += "<mo>+</mo>" + $e.value;}
            |   '-' e=multExpr {$value += "<mo>-</mo>" + $e.value;}
            )*
        ;
    
    multExpr returns [String value]
        :   e=atom {$value = $e.value;} 
            (   '*' e=atom {$value += "<mo>*</mo>" + $e.value;}
            |   '/' e=atom {$value += "<mo>/</mo>" + $e.value;}
            )*
        ; 
    
    atom returns [String value]
        :   INT {$value = "<mn>" + $INT.text + "</mn>";}
        |   '-' e=atom {$value = "<mo>-</mo>" + $e.value;}
        |   'sqrt[' exponent ']' {$value = "<msqrt><mrow>" + $exponent.value + "</mrow></msqrt>";}
        |   '(' exponent ')' {$value = "<mo>(</mo>" + $exponent.value + "<mo>)</mo>";}
        ;
    
    INT :   '0'..'9'+ ;
    NEWLINE:'\r'? '\n' ;
    WS  :   (' '|'\t')+ {skip();} ;
    
    语法表达式;
    解析返回[字符串值]
    :stat+{$value=$stat.value;}
    ;
    stat返回[字符串值]
    :exponent换行符{$value=”“++$exponent.value+“”;}
    |新线
    ;
    指数返回[字符串值]
    :e=expr{$value=$e.value;}
    (“^”e=expr{$value=”“++$value++++$e.value++;”
    )*
    ;
    expr返回[字符串值]
    :e=multExpr{$value=$e.value;}
    (“+”e=multExpr{$value+=“+”+$e.value;}
    |“-”e=multExpr{$value+=“-”+$e.value;}
    )*
    ;
    multExpr返回[字符串值]
    :e=atom{$value=$e.value;}
    ('*'e=atom{$value+=“*”+$e.value;}
    |“/”e=atom{$value+=“/”+$e.value;}
    )*
    ; 
    atom返回[字符串值]
    :INT{$value=”“+$INT.text+“”;}
    |“-”e=atom{$value=“-”+$e.value;}
    |'sqrt['exponent']'{$value=”“++$exponent.value+“”;}
    |“('exponent')”{$value=“(+$exponent.value+”)”;}
    ;
    INT:'0'..'9'+;
    换行符:'\r'?'\n';
    WS:(''|'\t')+{skip();};
    
    首先谈谈你的语法:

    • 您应该为规则的左侧和右侧提供唯一的标签(
      e1=atom('*'e2=atom…
    • 您可能希望创建单独的
      sqrt
      [
      标记,而不是一个
      sqrt[
      ,否则像
      “sqrt[9]”“
      (sqrt
      [
      之间的空格)这样的输入将无法正确处理
    • 一元负数的优先级通常低于指数运算
    rickythefox写道:

    平方根规则sqrt在原子中的位置似乎是可行的,但我很确定它应该在指数规则中的某个地方?还是应该

    不,没有问题:它应该有最高的优先级。谈到优先级,在您的情况下,通常的优先级表(从最低到最高)是:

    • 加减法
    • 乘法与除法
    • 一元负数
    • 指数化
    • 带括号的表达式(包括函数调用,如
      sqrt[…]
    rickythefox写道:

    语法允许完整的表达式,如2*(3+4)。我希望它也允许不完整的表达式,如2*(3+。作为ANTLR的一名完全新手,我不知道如何实现这一点。请向我指出正确的文档或给出一个示例

    这很棘手

    我真的只看到一种方法:在stat规则中,您首先强制解析器在令牌流中向前看,以检查前面是否真的有
    expr
    。这可以使用。一旦解析器确定有
    expr
    ,然后才解析所述表达式。如果没有
    expr
    ,请尝试匹配
    NEWLINE
    ,如果也没有
    换行符
    ,只需使用
    换行符
    (必须是不完整表达式的一部分!)以外的单个标记即可。(我将在下面发布一个小演示)

    rickythefox写道:

    如果我想扩展这个语法来实际执行计算,我可以以某种方式重用它还是必须复制和粘贴

    ANTLR解析器规则可以返回多个对象。这当然不是真的,因为Java方法(解析器规则本质上是)只能返回一个对象。解析器规则返回一个包含多个对象引用的对象。因此,您可以执行以下操作:

    stat returns [String str, double num]
      :  ...
      ;
    

    演示 考虑到我的所有提示,一个小型的工作演示可能如下所示:

    语法表达式;
    parse返回[String str,double num]
    @init{$str=”“;}
    :(统计)
    {
    $str+=$stat.str;
    $num=$stat.num;
    如果(!Double.isNaN($num)){
    System.out.println($stat.text.trim()+“=”+$num);
    }
    })+
    ;
    stat返回[String str,double num]
    :(expr)=>expr新行{$str=”“++$expr.str+”;$num=$expr.num;}
    |换行符{$str=”“;$num=Double.NaN;}
    |~NEWLINE{$str=”“;$num=Double.NaN;System.err.println(“忽略:“+$text”);}
    ;
    expr返回[String str,double num]
    :e1=multExpr{$str=$e1.str;$num=$e1.num;}
    (“+”e2=multExpr{$str+=“+”+$e2.str;$num+=$e2.num;}
    |'-'e2=multExpr{$str+=“-”+$e2.str;$num-=$e2.num;}
    )*
    ;
    multExpr返回[String str,double num]
    :e1=unaryExpr{$str=$e1.str;$num=$e1.num;}
    ('*'e2=unaryExpr{$str+=“*”+$e2.str;$num*=$e2.num;}
    |“/”e2=unaryExpr{$str+=“/”+$e2.str;$num/=$e2.num;}
    )*
    ; 
    unaryExpr返回[String str,double num]
    :“-”e=expexpexpr{$str=“-”+$e.str;$num=-1*$e.num;}
    |e=expexpexpr{$str=$e.str;$num=$e.num;}
    ;
    expexpxpr返回[String str,double num]
    :e1=atom{$str=$e1.str;$num=$e1.num;}
    (“^”e2=atom{$str=”“++$str++$e2.str+”;$num=Math.pow($num,$e2.num);}
    )*
    ;
    atom返回[String str]