既然何时是RTFM的答案?无论如何。你所要做的并不容易,因为Java是无上下文的(类型2)。尝试为初学者编写3型语言(Chomsky Hierarchy)的语法分析器。但我会尽力向你解释你需要做什么。
您将不得不为Java定义规则(在我的示例中,我将在java类中定义一个函数,其中小写字母为终端,大写字母为非终端)。终端不能继续得到,而非终端可以。
X - > Y表示X导出到Y X - > Y | Z表示X派生到Y或Z.
f是任何名称。 t是一个类型,如果我试图一路走下去,这不会是一个终端,但是由于我将类型定义为非可声明的,以使我的生活减轻痛苦,所以它是一个终端。 '(',')','{','}',','和''是终端。 Eps是Epsilon,没有任何意义。
S -> K t f(T) { N }
T -> t f | t f , T
F -> F, f | f
K -> k K | k
N -> L N | L
L -> f(F);
有了这个,我可以解析
final boolean equals(Object obj) {
compare(this, obj);
compare(obj, this);
}
这将导致:
S -> K t f(T) { N }
with K -> k
-> k t f(T) { N }
with T -> t f
-> k t f(t f) { N }
with N -> L N
-> k t f(t f) { L N }
with L -> f(F);
-> k t f(t f) { f(F); N }
with F -> f, F
-> k t f(t f) { f(f, F); N }
with F -> f
-> k t f(t f) { f(f, f); N }
with N -> L
-> k t f(t f) { f(f, f); L }
with L -> f(F)
-> k t f(t f) { f(f, f); f(F) }
...
-> k t f(t f) { f(f, f); f(f, f); }
-> k (=final) t(=boolean) f(=equals) (t(=Object) f(=obj)) { ... }
这证明s定义我的simplyfied的Java(当然不是,但至少我举了一个例子)。所以接下来我们要做的就是弄清楚如何从这些规则中得到一个语法树。
值得庆幸的是,这是比较容易的部分,因为所有你需要做的是改变线路是一棵树。所以S有孩子K t f(T){N}。 K有孩子K和K ...大写意味着一个节点有孩子,小写则表示它没有孩子。
最后一个问题,你不是以S开头,而是从已经写好的代码开始。这让你
K t f(T) { N } -> S
t f -> T
t f , T -> T
F, f -> F
f -> F
k K -> K
k -> K
L N -> N
N -> L
f(F); -> L
解析相反应该是这样的:
final boolean equals(Object obj) {
compare(this, obj);
compare(obj, this);
}
final -> k
boolean -> t
equals -> f
Object -> t
obj -> f
compare -> f
this -> f
k t f(t f) { f(f, f); f(f,f); }
with k -> K
K t f(t f) ...
with t f -> T
K t f(T) ...
...
这会从楼下搭建的树。
[编译器:原理,技术和工具](http://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools) – jason
作为一个方面说明,如果你想有一个字符串看起来适当在代码中构造,您可以使用逐字字符串文字。基本上,把'@'放在'''之前,然后你可以编写一个包含新行的字符串。 – svick
http://stackoverflow.com/questions/1669/learning-to-write-a-compiler –