楽しみのためだけに、非常に迅速で非常に汚い、そして明らかにバグのあるソリューションです。ねえ、少なくともそれはあなたの例を解決します!!!!
package parser;
import java.util.Collection;
import java.util.ArrayList;
import java.util.Arrays;
/**
*
* @author gpeche
*/
public class Parser {
private static abstract class Node {
String name;
String getName() { return name; }
abstract boolean isComposite();
Node(String name) { this.name = name; }
}
private static class PrimitiveNode extends Node {
@Override boolean isComposite() { return false; }
PrimitiveNode(String name) { super(name); }
@Override public String toString() { return "PrimitiveNode(\"" + name + "\")"; }
}
private static class CompositeNode extends Node {
Collection<Node> children = new ArrayList<Node>();
void addChild(Node childNode) { children.add(childNode); }
Collection<Node> getChildren() { return new ArrayList<Node>(children); }
@Override boolean isComposite() { return false; }
CompositeNode(String name) { super(name); }
@Override public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("CompositeNode(\"");
sb.append(name);
sb.append("\") { ");
boolean isFirstNode = true;
for (Node node: children) {
if (!isFirstNode) {
sb.append(", ");
}
sb.append(node.toString());
isFirstNode = false;
}
sb.append(" }");
return sb.toString();
}
}
// Parser state
int pos = 0;
String[] tokens;
static final String OPENING_PAR = "(";
static final String CLOSING_PAR = ")";
static final String OP_PLUS = "+";
static final String OP_MINUS = "-";
static final String OP_MULTIPLY = "*";
static final String OP_DIVIDE = "/";
static final String OP_MODULUS = "mod";
static final String OP_INT_DIVIDE = "div";
static final Collection<String> PARENTHESIS = Arrays.asList(OPENING_PAR, CLOSING_PAR);
static final Collection<String> OPERATIONS = Arrays.asList( OP_PLUS,
OP_MINUS,
OP_MULTIPLY,
OP_DIVIDE,
OP_MODULUS,
OP_INT_DIVIDE);
public Node parse(String treeRepresentation) {
tokenize(treeRepresentation);
return parseNode();
}
private void tokenize(String treeRepresentation) {
treeRepresentation = treeRepresentation.replace("(", " ( ");
treeRepresentation = treeRepresentation.replace(")", " ) ");
tokens = treeRepresentation.split("\\s+");
}
private Node parseNode() {
// check that current token is not a "syntax" token
String currentToken = tokens[pos];
if (PARENTHESIS.contains(currentToken)) {
throw new IllegalArgumentException(String.format("Invalid token %d, expected identifier. got %s", pos + 1, currentToken));
}
boolean isComposite = currentToken != null &&
(currentToken.startsWith("op") || // Accept identifiers as operations (function support :P)
OPERATIONS.contains(currentToken));
return isComposite? parseComposite() : parsePrimitive();
}
private Node parseComposite() {
CompositeNode composite = new CompositeNode(tokens[pos]);
pos++;
if (!OPENING_PAR.equals(tokens[pos])) {
throw new IllegalArgumentException(String.format("Invalid token %d, expected '(', got %s", pos + 1, tokens[pos]));
} else {
// Ignore opening parenthesis
pos++;
}
boolean nextIsIdentifier;
do {
composite.addChild(parseNode());
nextIsIdentifier = !PARENTHESIS.contains(tokens[pos]);
} while (nextIsIdentifier);
if (!CLOSING_PAR.equals(tokens[pos])) {
throw new IllegalArgumentException(String.format("Invalid token %d, expected ')', got %s", pos + 1, tokens[pos]));
} else {
pos++;
}
return composite;
}
private Node parsePrimitive() {
// Create primitive node and advance position
Node result = new PrimitiveNode(tokens[pos]);
pos++;
return result;
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Parser parser = new Parser();
Node parsedNode = parser.parse("op1 (op2 (t1 t2) t3)");
System.out.println(parsedNode.toString());
}
}