ANTLR-允许不完整语法
我使用ANTLR解析数学表达式的字符串,并使用MathML标记它们 现在我有下面的语法。现在我有三个问题:ANTLR-允许不完整语法,antlr,antlr3,Antlr,Antlr3,我使用ANTLR解析数学表达式的字符串,并使用MathML标记它们 现在我有下面的语法。现在我有三个问题: 语法允许完整的表达式,如2*(3+4)。我想要 它还允许不完整的表达式,例如作为 完全是ANTLR的新手,我不知道如何做到这一点。 请给我指出正确的文件或举个例子 平方根规则sqrt在原子中的位置似乎 但我很确定它应该在指数中的某个地方 规则?还是应该 如果我想扩展这个语法来实际执行 计算,我可以重新使用它吗,还是必须复制粘贴 对于我的语法方面的任何其他评论或建议,我也非常感谢,因为我现在
2*(3+4)
。我想要
它还允许不完整的表达式,例如作为
完全是ANTLR的新手,我不知道如何做到这一点。
请给我指出正确的文件或举个例子sqrt
在原子中的位置似乎
但我很确定它应该在指数中的某个地方
规则?还是应该
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和“sqrt[9]”“
之间的空格)这样的输入将无法正确处理[
- 一元负数的优先级通常低于指数运算
- 加减法
- 乘法与除法
- 一元负数
- 指数化
- 带括号的表达式(包括函数调用,如
)sqrt[…]
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]