[英]How do I print the parse tree generated by the parser for a given grammar in java?
I have a scanner which returns an ArrayList of token objects.我有一个扫描仪,它返回一个令牌对象的 ArrayList。 Each token object consists of the token and the token type.每个令牌 object 由令牌和令牌类型组成。 My goal is to parse the tokens into a tree using the following grammar:我的目标是使用以下语法将标记解析为树:
expression → term { + term }
term → factor { - factor }
factor → piece { / piece }
piece → element { * element }
element → ( expression ) | NUMBER | IDENTIFIER
I managed to code the following parser in java:我设法在 java 中编写了以下解析器:
public class parserModule {
private ArrayList <Tokens> tokens;
public void consume_token() {
tokens.remove(0);
}
public String next_token(String func) {
if (func == "type") {
return tokens.get(0).getType();
}
else {
return tokens.get(0).getToken();
}
}
public interface PTNode {
PTNode getLeftSubtree();
PTNode getRightSubtree();
}
class PTInteriorNode implements PTNode {
char operator;
PTNode left;
PTNode right;
public PTInteriorNode(char operator, PTNode left, PTNode right) {
this.operator = operator;
this.left = left;
this.right = right;
}
char getOperator() {
return operator;
}
@Override
public PTNode getLeftSubtree() {
return left;
}
@Override
public PTNode getRightSubtree() {
return right;
}
}
class PTLeafNode implements PTNode {
private double number;
private String identifier;
public PTLeafNode(double n) {
number = n;
}
public PTLeafNode(String n) {
identifier = n;
}
double getNumber() {
return number;
}
String getIden() {
return identifier;
}
@Override
public PTNode getLeftSubtree() {
return null;
}
@Override
public PTNode getRightSubtree() {
return null;
}
}
PTNode parseElement() {
if (next_token(" ").contentEquals("(")) {
consume_token();
PTNode tree = parseExpression();
if(next_token(" ").contentEquals(")")) {
consume_token();
return tree;
}
else {
System.out.println("ERROR") ;
}
}
else if(next_token("type").equals("NUMBER")) {
Double n = Double.valueOf(next_token(" "));
consume_token();
return new PTLeafNode(n);
}
else if(next_token("type").equals("IDENTIFIER")) {
String n = next_token(" ");
consume_token();
return new PTLeafNode(n);
}
else {
System.out.println("ERROR");
}
return null;
}
PTNode parsePiece() {
PTNode tree = parseElement();
while (next_token(" ").equals("*")) {
consume_token();
tree = new PTInteriorNode('*', tree, parseElement());
}
return tree;
}
PTNode parseFactor() {
PTNode tree = parsePiece();
while (next_token(" ").equals("/")) {
consume_token();
tree = new PTInteriorNode('/', tree, parsePiece());
}
return tree;
}
PTNode parseTerm() {
PTNode tree = parseFactor();
while (next_token(" ").equals("-")) {
consume_token();
tree = new PTInteriorNode('-', tree, parseFactor());
}
return tree;
}
PTNode parseExpression() {
PTNode tree = parseTerm();
while (next_token(" ").equals("+")) {
consume_token();
tree = new PTInteriorNode('+', tree, parseTerm());
}
return tree;
}
public void Parser(ArrayList <Tokens> tokenList) {
tokens = tokenList;
}
}
If the input is: 4 * (8 + 2 / x - 1)
如果输入是: 4 * (8 + 2 / x - 1)
My output goal is:我的 output 目标是:
* : PUNCTUATION
4 : NUMBER
+ : PUNCTUATION
8 : NUMBER
- : PUNCTUATION
/ : PUNCTUATION
2 : NUMBER
x : IDENTIFIER
1 : NUMBER
I have no clue how to traverse this.我不知道如何遍历这个。
Basically you want a recursive pre-order traversal of the parse tree, with an integer depth argument included so you know how far to indent Here's a simple example (guaranteed not necessarily working code, but it should give you the general idea):基本上你想要一个解析树的递归前序遍历,其中包含一个 integer深度参数,所以你知道缩进多远这是一个简单的例子(保证不一定工作代码,但它应该给你一般的想法):
public class Node<T,V> {
T type;
V value;
Node<T,V> left, right;
}
// ...
private static final int INDENT_WIDTH = 4;
// ...
public void printParseTree(Node root) {
preOrder(root, 0);
}
private void preOrder(Node root, int depth){
if (root != null) {
for (int i = 0; i < depth * INDENT_WIDTH; ++i) {
System.out.print(" ");
}
System.out.println(root.value.toString() + ":" + root.type.toString());
preOrder(root.left, depth+1);
preOrder(root.right, depth+1);
}
}
Adapt as needed for your application.根据您的应用程序进行调整。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.