提问人:Seifeldin Elkasrawy 提问时间:11/7/2023 最后编辑:Seifeldin Elkasrawy 更新时间:11/10/2023 访问量:76
如何使用 Java 在控制台中打印正确的解析树?
How to print a proper parse tree in console using Java?
问:
我正在编写一个使用 java 模拟 6 个编译器阶段的程序。目前,卡在了第二阶段的解析树的打印中,语法分析器。经过一些调试,我已经知道我的问题是什么。父节点和子节点是正确的,但在视觉上以错误的深度显示。
输入:z=y*y+x*3
当它到达具有子节点的 * 符号时,它首先显示其子节点,然后再显示其同级节点,该节点也是另一个 *,因为递归。
public static void displayParseTree(ParseTreeNode node, int depth) {
if (node != null) {
StringBuilder indent = new StringBuilder();
for (int i = 0; i < depth; i++) {
indent.append(" ");
}
//if node has children print / -> child1 \ -> child2
System.out.print(indent.toString() + node.token.getValue());
// Check if the node has any children.
if (!node.children.isEmpty()) {
System.out.println("");
System.out.print("/ ");
System.out.println(" \\");
// Print the left child node.
displayParseTree(node.children.get(0), depth + 1);
// Print the right child node.
displayParseTree(node.children.get(1), depth + 1);
System.out.println("");
}
}
}
万一img打不开,这是我目前的输出:
Please enter the source code:
z=y*y+x*3
Source Form: z=y*y+x*3
Math Form: z=yxy+xx3
Lexical Analyzer: id1=id2*id2+id3*3
Syntax analysis completed. The input is valid.
=
/ \
id1 +
/ \
*
/ \
id2 id2
*
/ \
id3 3
我希望我的输出看起来更像这样:
=
/ \
id1 +
/ \
* *
/ \ / \
id2 id2 id3 3
编辑:我有点硬编码它(不为此感到自豪),但我会把它留在那里,直到我找到更好的方法
public static void displayParseTree(ParseTreeNode node, int depth) {
if (node != null) {
StringBuilder indent = new StringBuilder();
for (int i = 0; i < depth; i++) {
indent.append(" ");
}
//if node has children print / -> child1 \ -> child2
if (node.token.getValue().equals("=")){
System.out.println(" " + indent.toString() + node.token.getValue());
}
// Check if the node has any children.
if (!node.children.isEmpty()) {
if (node.children.get(0).token.getValue().equals("*") && node.children.get(1).token.getValue().equals("*")) {
System.out.print("/ ");
System.out.println(" \\");
for (int i = 0; i < 2; i++) {
System.out.print(node.children.get(i).token.getValue() + " ");
}
System.out.println("");
System.out.print("/ ");
System.out.print(" \\ ");
System.out.print(" / ");
System.out.println(" \\");
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++)
System.out.print(node.children.get(i).children.get(j).token.getValue() + " ");
}
System.out.println("");
}
else {
// Print the left child node.
System.out.print("/ ");
System.out.println(" \\");
for (int i = 0; i < 2; i++) {
System.out.print(node.children.get(i).token.getValue() + " ");
}
System.out.println("");
displayParseTree(node.children.get(0), depth + 1);
// Print the right child node.
displayParseTree(node.children.get(1), depth + 1);
}
}
}
}
电流输出:
=
/ \
id1 +
/ \
* *
/ \ / \
id2 id2 id3 3
答:
-1赞
Seifeldin Elkasrawy
11/10/2023
#1
我想通了。虽然我认为可以有更好的解决方案,但这就是我设法想出的。 因为,只有乘法和除法运算符才能达到相同的深度,所以我专门为它们做了一个条件。首先检查两个运算是否都是 * 或 /,如果是,则打印 / \ 分支,然后打印运算,然后打印其所有子项的分支,即 4 个 / \ / \,然后使用嵌套循环在同一行上打印他们的两个子项,否则正常执行所有操作。就是这样。在那之后,只需调整空间即可获得我正在寻找的输出。
public static void displayParseTree(ParseTreeNode node, int depth) {
if (node != null) {
StringBuilder indent = new StringBuilder();
for (int i = 0; i < depth; i++) {
indent.append(" ");
}
//if node has children print / -> child1 \ -> child2
if (node.token.getValue().equals("=")){
System.out.println(" " + indent.toString() + node.token.getValue());
}
// Check if the node has any children.
if (!node.children.isEmpty()) {
if (node.children.get(0).token.getValue().equals("*") && node.children.get(1).token.getValue().equals("*") ||
node.children.get(0).token.getValue().equals("/") && node.children.get(1).token.getValue().equals("/")) {
System.out.print(" / ");
System.out.println(" \\");
for (int i = 0; i < 2; i++) {
System.out.print(" "+ node.children.get(i).token.getValue() + " ");
}
System.out.println("");
System.out.print(" / ");
System.out.print(" \\ ");
System.out.print(" / ");
System.out.println(" \\");
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++)
System.out.print(" "+ node.children.get(i).children.get(j).token.getValue() + " ");
}
System.out.println("");
}
else {
// Print the left child node.
System.out.print(" / ");
System.out.println(" \\");
for (int i = 0; i < 2; i++) {
System.out.print(" " + node.children.get(i).token.getValue() + " ");
}
System.out.println("");
displayParseTree(node.children.get(0), depth + 1);
// Print the right child node.
displayParseTree(node.children.get(1), depth + 1);
}
}
}
}
Please enter the source code:
z=y*y+x*3
Source Form: z=y*y+x*3
Math Form: z=yxy+xx3
Lexical Analyzer: id1=id2*id2+id3*3
Syntax analysis completed. The input is valid.
=
/ \
id1 +
/ \
* *
/ \ / \
id2 id2 id3 3
评论
0赞
user207421
11/10/2023
“只有乘法运算符和除法运算符才能达到相同的深度”:当您使用括号时,这种情况是正确的。找到一个通用的解决方案。
评论