jep学习文档
温柔似野鬼°
558次浏览
2021年01月28日 17:09
最佳经验
本文由作者推荐
阅兵的意义-北京美术大学
JEP(Java Expression Parser)
学习笔记
By shenweifeng
2012-9-25 in HangZhou
JEP
基本用法
1
、
入门
2
、
错误处理
3
、
计算表达式
4
、
替代的解析和计算方法
5
、
缩略的乘法
入门
在项目中使用
JEP
的类包是很简单的!下面的步骤将会使用很快入门。
1
、
下载
JEP
包,下载格式为
ZIP
2
、
解压缩该包
3
、
移动
到你选择的目录中
4
、
重要:< br>为了当编译你的程序时
Java
编译器能找到
jep
类,编译器需要知 道
jep
的位
置。
所以你需要添加
.jar
文件的路径到你 的
CLASSPATH
环境变量中。
(如果你不清楚
如
何
使
用
,
请
读
这
里
)
;
你
的
CLASSPATH
变
量
应
该
包
含
某些
东
西
如
C:
,取决于你
jar
包放置的位置 。或者,你也许需要
在你的
JAVA IDE
中设置
jar
包的位置,使编译器能找到类库。
5
、
在你的程序中,创建一个解析器对象,如:
arser = new .
JEP
();
6
、
添加标准函数和常量,如果你想有能力使用三角函数和
pi,e
计算表达式。
myParser.
addStandardFunctions()
;
myParser.
addStandardConstants()
;
7
、
通常情况下,
你需要具体指明哪些变量能在表达式中被使用。
如果一个变量在表达式被
解析时还没被添加,解析器将声明表达式是不合法的(这种情况能被改 变通过使用
允
许未声明的变量
)。
添加变量
x
并且初始化为
0
,
myParser.
addVariable(
;
8
、
解析表达式并计算它
myParser.
parseExpression (ExpressionString)
;
result = myParser.
getValue()
;
9
、
变量值可以通过
addVariable(String, double)
改变
样本小应用程序提供了更多更广泛的表现来展示解析器的使用。
错误处理
错误可能发生在解析表达式过程中,
也可能发生在计算表达式过程 中。
方法
handError()
将报
告一个错误是否已经发生在最近的行为 中(或解析,或计算)
。如果返回值是
true,
你能使用
getError Info()
方法获得已发生错误的进一步错误信息。
计算表达式
4
个计算表达式的方法是可以获得的:
getValue():
当你期望一个正常的浮点运算值时使用
getComplexValue():
当你期望一个复数时使用
getValueAsObject():
返回结果为一个对象(任意类型)
evaluate(Node root):
从根节点计算一颗树(一种数据结构)并且返回一个对象。
前两种方法 内在也算是
getValueAsObject()
,通过一些必须地转换就能变成
d ouble
类型或者
Complex
类型。
替代的解析和计算方法
有一种替代方法解析和计算表达式,
该方 法为计算机应用提供了更多的灵活性,
特别是
在处理一系列相关的等式时。它们是:
public Node
parse(String expression)
throws ParseException
public Object
evaluate(Node node)
throws Exception
分别解析和计算表达式。这些能被使用如下:
try
{
量
}
te(node1);
Node node2 = (
Object val2 = te(node2);
n(
// Alternative syntax
Node node1 = (
实际使用中需要打开允许赋值和使用未声明变
catch(ParseException e)
{
}
catch(Exception e)
}
因此,
它更容易记录一系列等式。
注意使用这种语法,
异常需要 被捕获而且
getTopNode
()
方法将不返回有意义的值。
{
n(
n(
缩略的乘法
你能使用缩略的乘法通过使用
setImplicitMul(true)
。
默认的设置是
false(
没有缩略乘法
)
。
缩略乘法允许表达式例如“
2
x
”能被解释为“
2*x
”
。注意两个变量之间的空格是必须的
使它们被解释为乘法。这同样适用于变脸后跟随一个数字。 举个例子“
y 3
”被解释为“
y*3
”
,
但是
y 3
被解释为单个名为
y3
的变量。如果一个数字位于变量之前,它们之间的空格是不需 要
的,缩略乘法照样有效。
变量
基础
允许未声明的变量
获得变量队列
赋值(
Assignment
)
变量观察者
基础
变量有两种处理方式可供选择:
1
、
< br>不允许未声明的变量(默认)
:在这种情况下,解释一个表示式前添加表达式中的变量
时 必须的。添加通过使用
addVariable()
方法实现。
2
、
允许未声明的方法:如果你允许未声明的变量,它们将在表达式被解析 时自动地添加到
符号表(
symbol table
)中。
在一个表达式已经被解析后,变量值可以通过使用
addVaribale()
或
setVariable()
方法来进行
更新。这样就允许使用不同的值对表达式进行重复计算 。
一个变量的值可以通过使用
getVarValue()
方法 进行查询。
一个更进一步的方法是使用
getVar()
,返回一个代表该变量的对象。
这里的变量可能是常量,即不能改变值。 添加一个新的常量使用
addConstant,
添加一个新的
变量使用
ad dVariable;
符号表类(
SymbolTable
)存储代表变 量的对象而不仅仅是它们的值。该类的
get
和
put
已经
过时,不 赞成使用。这导致一个运算上的细微提高。
允许未声明的变量
使其能够解析未声明的变量,使用方法
setAllowUndeclared(true)
。
默认的设置是
false(
不允许未声明的变量
)
。
如
果
你
不
清
楚
声
明
变
量名
将
会
出
现
在
将
要
解
析的
表
达
式
中
,
你
可
以
使用
setAllowUndeclare(true)
。设置该选择后,解析表达式前将变 量添加到表达式中将不是必须
的了。当解析时如果一个新变量被发现,它被自动的添加到符号表中。看
获得变量队列
,你可以
读到有关怎么访问这些变量的方式。
获得变量队列
在未声明对象允许的情况下解析表达式,
变量和常量队列被添 加进解析器中,
可以通过方法
getSymbolTable
获得。该方法 是最有效的当未声明变量选项被选中后。方法返回值是一个
SymbolTable
对象。注意
SymbolTable
继承
HashTable
。
赋值(
Assignment
)
赋值允许变量的值被设置通过使用 等式中的“
=
”操作符,这样,执行操作例如
x=3,
Y=x^2
,然后
y
将获得值
9
。赋值能被使用通过标准的
JEP
包, 没有需要用到
树中的任何包。为了打开赋值功能,
JEP
的方法
se tAllowAssignment(true)
需要调用。
// standard initialisation
JEP j = new JEP();
ndardConstants();
ndardFunctions();
plex();
owUndeclared(true);
licitMul(true);
// switch assignment facilities on
owAssignment(true);
// parse assignment equations
xpression(
// evaluate it - no need to save the value returned
ueAsObject();
// parse a second equation
xpression(
ueAsObject();
// an equation involving above variables
xpression(
Object val3 = ueAsObject();
n(
变量观察者
符号表(
Symbol)和变量(
Variable
)都实现了观察者模式。这允许对象被通知当一个新的
变量被创建或者值被改变。这里有个使用的例子:
public class MyObserver implements Observer
{
public void initialise()
{
SymbolTablest = bolTable();
erver(this);
erverToExistingVariables(this);
}
public void update(Observable arg0, Object arg1)
{
if(arg0 instanceof Variable)
println(
else if(arg0 rvable)
{
println(
// This line is vital to ensure that
// any new variable created will be observed.
((Variable) arg1).addObserver(this);
}
}
}
数据类型
JEP
支持大量的 数据类型。这些包括数字(
numbers
)
,字符串
(strings)< br>,矢量
(vectors)
,
复数
(Complex
num bers)
。
Numbers
默认的表现方式是
double
类型。 然而它也是可以改变表
现形式的正如小节使用
自定义的
number
类
。
Strings
Strings
能通过使用双引号加入到 表达式中。它们能被连接通过使用“
+
”运算符,也能进行
比较通过使用“
= =
”和“
!=
”运算符。一个包含字符串的样例表达式是“
foo
”
+
“
bar
”
==
“
foobar
”,将被
JEP
计算为
1
(
true
)
;
添加字符串变量,使用方法
addVariabe(String name,Object value)
。如果一个表达式的结果是
一个字符串,该值可以通过 调用方法
getValueAsObject()
获得。
Vectors
Vectors
被要求为
Double
元素的一个 集合。一个
Vector
是一系列的值,通过“,
“分隔,使
用方括号”[
“,
”
]
“包围。一个包含
Vector
的样例为:
[3, 4, 5]*2
它将被
JEP
计算为
[6,
8
,
10]
。
添加一个
vector
为变量 使用方法
addVariable(String name,Object
Value)< br>。如果一个表达式的结果为一个
vector
,可以通过调用方法
getVal ueAsObject()
获得。
Complex numbers
如
果
你想
在
表达
式
中使用
Complex
numbers
,你
要
在创
建
了解
析
器对 象
后
调用
addComplex()
方法。这将添加一个虚数单位
i
。
2
个解析器函数
re()
和
im()
也被添加, 可以使
用它们获取复数的实数部分和虚数部分。
你需要去导入
x
才能操作表达式中的复数。
通过使用虚数单位
i
,你可以操作表达式 中的复数。一个简单的例子是(
1+2*i
)
^3
。当前
(
re,im
)标记是不支持的。
从表达式中获取一个 复数,你需要使用
getComplexValue()
方法。它将进行运算并返回一个
Complex
对象。注意这个类不仅实现了
Complex numbers
的运算,而且用来返回运算结果。
在运算前,通过使用
addVariable(String name,doublere, doubleim)
可以添加一个复数变量或常
量到解析器中。它包含三个参数:变量的名称, 实数部分和虚数部分。
使用自定义的
Number
类
默认的当一个表达式例如
“
1+2
“
被解析,
常 量
1
和
2
在内部将会被解析为
Double
对象。
在大多数情况下这是好的。
但是在某些情况下,
你也许想要使用自定义的类来作为表现形式。< br>
这是可行的通过创建一个实现了
NumberFactory
借口 的
Number
类。
它包含了一个方法
createNumber(String
value),
该方法将返回一个初始化 参数值的对象。你能加载你的自定义
number
factory
使用
JE P
构造器
JEP(booleantraverse_in,
Boolean
allowUndeclared_in,
Boolean
implicitMul_in, NumberFactorynumberFactory_in)
。
自 定义的对象需要操作通过自定义的函数,
你可以创建参考下面的使用说明,
位于自定
义 函数页面。
自定义的类型
在
大
多
数
情
况
下
,
你
只
需
要
使
用
JEP
提
供
的
已
存
在
的
少
量
的
类
型
(
Double,Complex,Vect or,String
)
。但是假如你需要计算包含其他类型的表达式。这是可行的
通过 使用
addVariable(String name,Object value)
去添加 任意类型的变量。
一个变量类型唯一有
关的地方在函数类中。
当 一个表达式被计算,变量的值被类中的方法操作。这些包括操作(加法和减法)
,同
样还有函数
Sine
和
Cosine
。不修改源码的情况下,只有默认类型能被这些类操 作。所以,
为了有能力操作自己的类型,
你需要去修改这些类,
或者编写你自己的函数 类依照在自定义
函数小节中描述的。
运算符
内嵌的运算符
所有常用的算术操作都被支持。
Boolean< br>操作也都被支持。
Boolean
表达式计算后为
1
或
0(分别代表真和假)
。
符号
表示该运算符能被指定对象的使用。关于运 算符优先级可以参考语法部分获取详
细信息。