我发布了类似的问题here,但由于我没有正确解释,因此已经关闭了。 我会再次尝试解释我的问题。
我设法写了LexicalAnalyzer,它会将以下内容标记为“public”,“class”,“A”,“{”,...,“if”,“(”,...,“}”< / p>
string seq = "public class A " +
"{ " +
"public A() " +
"{ " +
"if(1==2) " +
"{ " +
"} " +
"else " +
"{ " +
"} " +
"} " +
"} "
现在,我需要将其解析为树。在我阅读时,最好以采用规则的方式构造解析器。同时我需要编写“if”语句的规则“将传递给解析器,最后一个将构建解析树。将来,我将为”class“和其他添加规则。
解析我的意思是最终我会得到类似的树like here in the right
我的问题是如何实现规则和解析器?你能指点我或举一个简单的例子吗?
我已经阅读了一些帖子,但我找不到能帮助我做我需要的东西。
P.S。如果仍然不清楚,请不要关闭帖子,但告诉我,我会改变它。
谢谢
答案 0 :(得分:1)
从什么时候RTFM回答?无论如何。你要做的事情并不容易,因为Java是无上下文的(类型2)。尝试为初学者编写类型为3的语言(Chomsky Hierarchy)的语法分析器。但我会尽力向你解释你还需要做些什么。
您必须为Java定义看起来像这样的规则(在我的示例中,我将在java类中定义一个函数,其中小写字母是终端,大写字母是非终端)。非终端可以进一步导出终端。
X - &gt; Y表示X派生于Y. X - &gt; Y | Z表示X派生于Y或Z.
f是任何名字。 t是一个Type,如果我试图一直走的话,这不会是一个终端,但是因为我定义的类型是不可声明的,以使我的生活不那么痛苦,所以它是一个终端。 '(',')','{','}',','和''是终端。 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定义了我简单的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) ...
...
哪个会从下面构建树。