+ -
当前位置:首页 → 问答吧 → Java问题请教

Java问题请教

时间:2014-02-08

来源:互联网

本人已经花了几天的时间,但是还未能了解这个程式怎样去执行,还望各位朋友能够简单地解释一下。
这是一个recursive-descent parser,就是入一条算式就可以得到答案。这个程式当中也配合先乘除后加减的原则。
比如算式是10-3*2,那这些数字跟operator是在程式中怎样运作的?

sample code在
http://www.mhprofessional.com/getpage.php?c=computing_downloads.php&cat=112#S-U

下面的 The Art of Java一个项目。下载后打开chapter02的file就可以看到。

谢谢大家

作者: sense2000   发布时间: 2014-02-08

可能佢啲 method name 改得唔好, 叫咗做 evalExp1,2,3,4......之类.

如果细心啲睇, 可睇得出每一个 evalExpN 都代表一个 expression (production rule).

Expression 用来描述一堆 tokens 的组成.

Grammar 就系整个 language 的语法描述.

例如, chap 2 嗰个 grammar 的简化版用 BNF 描述出来好似系咁的:

exp1 = variable '=' exp2
exp2 = exp3 ('+' | '-') exp3
exp3 = exp4 ('*' | '/' | '%') exp4
exp4 = exp5 '^' exp4
exp5 = ('+' | '-') exp6
exp6 = '(' exp2 ')' | atom
atom = number | variable
number = a valid result of Double.parseDouble(token)
variable = [a-z]

每一个 expression 被 evaluate 时都会因应个 operator 而作相应运算. 各 operator 的先后次序, 可由上 grammar 看出的先后次序:

1. -9
2. (-9)^(2*2/3%4)
3. ((-9)^(2*2/3%4)) + (1) - (2)
4. a=((-9)^(2*2/3%4)) + (1) - (2)

要完全理解 recursive decent parser 可能要认识当中涉及的资料结构同背后的思想.资料结构由最基本的字元, 英文字, 数字, 空白, token, delimitor 等等.背后的思想如 EBNF grammar, production rule, procedure(我估即系 expression?), regular expression 等等.

如果简化个 program 你理唔理解到丫?
例如只做加减运算, 无变数定义和代入.
明白后再渐渐加入其它功能, 再逐中理解.
引用:原帖由 sense2000 於 2014-1-6 14:25 发表
本人已经花了几天的时间,但是还未能了解这个程式怎样去执行,还望各位朋友能够简单地解释一下。
这是一个recursive-descent parser,就是入一条算式就可以得到答案。这个程式当中也配合先乘除后加减的原则。
比如 ...
[ 本帖最后由 a8d7e8 於 2014-1-6 03:09 PM 编辑 ]

作者: a8d7e8   发布时间: 2014-02-08

非常感谢你的回答。我现在开始有一点点明白了。

比如说 2+3

1 getToken拿到 ’2‘ 这个token及token type
2 之后result这个值是从方法之中的方法代入。由於第一个token不是( 及 ),所以就移动至atom()。
3 在atom()中,把这个 ’2‘ 的格式由本来的String变成 double;
4 之后再进行getToken(),拿到 ’+‘ 这个token及其token type;
5 由於是加号,由5-3的方法均不适用,result(就是2)就回到方法2
6 根据方法2,
while((op = token.charAt(0)) == '+' || op == '-') {
getToken();
partialResult = evalExp3();
switch(op) {
case '-':
result = result - partialResult;
break;
case '+':
result = result + partialResult;
break;
}
由於是 + 号,故此再进行getToken(),拿到3这个token;
7 之后再把3变成double type及代入partialResult;
8 再进行2+3,并将之代入result,得出答案。

作者: sense2000   发布时间: 2014-02-08

再比如 10+2*3

1. 根据getToken()的number,
else if(Character.isDigit(exp.charAt(expIdx))) { // is number
while(!isDelim(exp.charAt(expIdx))) {
token += exp.charAt(expIdx);
expIdx++;
if(expIdx >= exp.length()) break;
}
tokType = NUMBER;
}
如果连着是数字而不是operator的话,就会不断loop这一部分,第一及第二token就会加起来成为一个token。这里先拿到1,再loop一次,拿到0,由於是String type,1+0就变成10;再在atom()把这个token变成double type;

2之后在atom()里的getToken()拿到 + 这个token;
3 由於方法5到方法3不适用,就回到方法2;
4 在方法2确定是 + , 就执行 getToken(), 拿到2这个token;
5 同样,在代入partialResult过程中,回到atom(),并把2变成double type,代入atom()的result;
6 执行atom()中的getToken(),得到*这个token;
7 再回到方法3,却认是*,就执行方法3的getToken(),得到3这个token;
8 在方法3的代入partial result过程中,在atom()把3变成double type;
9 执行atom的getToken(), 由於
// Check for end of expression.
if(expIdx == exp.length()) {
token = EOE;
return;
expIdx跟exp.length相等,getToken()终止运作;
10 返回方法3,进行 2*3,代入方法3的result,再把之代入方法2的partial result;
11 进行10+6, 代入方法2的result, 得出答案。

作者: sense2000   发布时间: 2014-02-08

不知道我的理解对不对。
但无论如何,多谢你悉心ge提点~~~

作者: sense2000   发布时间: 2014-02-08

咦原来我有度错咗. 不过唔紧要你应该睇/试得出.

你只要识得一层一层由地下开始起楼, 就可以起到摩天大楼.
引用:原帖由 sense2000 於 2014-1-7 03:15 发表
不知道我的理解对不对。
但无论如何,多谢你悉心ge提点~~~

作者: a8d7e8   发布时间: 2014-02-08

大概 call tree 10 + 2*3
复制内容到剪贴板代码: evalExp2 -- evalExp3 -- evalExp4 -- evalExp5 -- evalExp6 -- atom -- 10
+
evalExp3 -- evalExp4 -- evalExp5 -- evalExp6 -- atom -- 2
*
evalExp4 -- evalExp5 -- evalExp6 -- atom -- 3

作者: form5   发布时间: 2014-02-08

复制内容到剪贴板代码:evalExp2 -- evalExp3
+
evalExp3
=>
复制内容到剪贴板代码:evalExp2
result = evalExp3()
if op is '+' or '-'
partialResult = evalExp3()
switch(op)
case '-': result = result - partialResult
case '+': result = result + partialResult

作者: form5   发布时间: 2014-02-08

recursive-descent 呢度 大概 意思

evalExp2 -- evalExp3 -- evalExp4 -- evalExp5 -- evalExp6 -- atom -- 10

作者: form5   发布时间: 2014-02-08

引用:原帖由 form5 於 2014-1-11 04:27 AM 发表
evalExp2 -- evalExp3
+
evalExp3=>evalExp2
result = evalExp3()
if op is '+' or '-'
partialResult = evalExp3()
switch(op)
case ...
呢度evalExp3 return result 先,所以剩除先过加减

作者: form5   发布时间: 2014-02-08