This commit is contained in:
Luke 2025-04-23 09:29:16 +08:00
parent 157f1e2f11
commit cd402653cb
6 changed files with 70 additions and 106 deletions

View File

@ -52,8 +52,6 @@ public class JsonFormatter {
} }
private static void appendIndent(StringBuilder sb, int indent) { private static void appendIndent(StringBuilder sb, int indent) {
for (int i = 0; i < indent; i++) { sb.append(" ".repeat(Math.max(0, indent))); // 两个空格
sb.append(" "); // 两个空格
}
} }
} }

View File

@ -4,7 +4,6 @@ import org.jcnc.snow.compiler.lexer.LexerEngine;
import org.jcnc.snow.compiler.lexer.token.Token; import org.jcnc.snow.compiler.lexer.token.Token;
import org.jcnc.snow.compiler.lexer.utils.TokenPrinter; import org.jcnc.snow.compiler.lexer.utils.TokenPrinter;
import org.jcnc.snow.compiler.parser.ParserEngine; import org.jcnc.snow.compiler.parser.ParserEngine;
import org.jcnc.snow.compiler.parser.ast.ASTJsonSerializer;
import org.jcnc.snow.compiler.parser.context.ParserContext; import org.jcnc.snow.compiler.parser.context.ParserContext;
import org.jcnc.snow.compiler.parser.ast.Node; import org.jcnc.snow.compiler.parser.ast.Node;
import org.jcnc.snow.compiler.parser.ast.ASTPrinter; import org.jcnc.snow.compiler.parser.ast.ASTPrinter;
@ -33,14 +32,14 @@ public class Main {
// 3. 可读地打印 AST // 3. 可读地打印 AST
ASTPrinter.print(ast); ASTPrinter.print(ast);
// 1) 输出紧凑 JSON // // 1) 输出紧凑 JSON
String compact = ASTJsonSerializer.toJsonString(ast); // String compact = ASTJsonSerializer.toJsonString(ast);
System.out.println("=== Compact JSON ==="); // System.out.println("=== Compact JSON ===");
System.out.println(compact); // System.out.println(compact);
//
// 2) 输出美化后的 JSON // // 2) 输出美化后的 JSON
System.out.println("=== Pretty JSON ==="); // System.out.println("=== Pretty JSON ===");
System.out.println(JsonFormatter.prettyPrint(compact)); // System.out.println(JsonFormatter.prettyPrint(compact));
} }
} }

View File

@ -32,21 +32,21 @@ public class ASTJsonSerializer {
private static String moduleToJson(ModuleNode m) { private static String moduleToJson(ModuleNode m) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("{\"type\":\"Module\",") sb.append("{\"type\":\"Module\",")
.append("\"name\":").append(quote(m.getName())).append(","); .append("\"name\":").append(quote(m.name())).append(",");
// imports // imports
sb.append("\"imports\":["); sb.append("\"imports\":[");
for (int i = 0; i < m.getImports().size(); i++) { for (int i = 0; i < m.imports().size(); i++) {
ImportNode imp = m.getImports().get(i); ImportNode imp = m.imports().get(i);
sb.append("{\"type\":\"Import\",\"module\":") sb.append("{\"type\":\"Import\",\"module\":")
.append(quote(imp.moduleName())).append("}"); .append(quote(imp.moduleName())).append("}");
if (i + 1 < m.getImports().size()) sb.append(","); if (i + 1 < m.imports().size()) sb.append(",");
} }
sb.append("],"); sb.append("],");
// functions // functions
sb.append("\"functions\":["); sb.append("\"functions\":[");
for (int i = 0; i < m.getFunctions().size(); i++) { for (int i = 0; i < m.functions().size(); i++) {
sb.append(functionToJson(m.getFunctions().get(i))); sb.append(functionToJson(m.functions().get(i)));
if (i + 1 < m.getFunctions().size()) sb.append(","); if (i + 1 < m.functions().size()) sb.append(",");
} }
sb.append("]}"); sb.append("]}");
return sb.toString(); return sb.toString();
@ -156,9 +156,9 @@ public class ASTJsonSerializer {
private static String binaryToJson(BinaryExpressionNode b) { private static String binaryToJson(BinaryExpressionNode b) {
return "{\"type\":\"BinaryExpression\"," return "{\"type\":\"BinaryExpression\","
+ "\"left\":" + exprToJson(b.getLeft()) + "," + "\"left\":" + exprToJson(b.left()) + ","
+ "\"operator\":" + quote(b.getOperator()) + "," + "\"operator\":" + quote(b.operator()) + ","
+ "\"right\":" + exprToJson(b.getRight()) + "\"right\":" + exprToJson(b.right())
+ "}"; + "}";
} }
private static String idToJson(IdentifierNode id) { private static String idToJson(IdentifierNode id) {

View File

@ -15,58 +15,58 @@ public class ASTPrinter {
private static void print(Node n, int indent) { private static void print(Node n, int indent) {
String pad = " ".repeat(indent); String pad = " ".repeat(indent);
if (n instanceof ModuleNode m) { switch (n) {
System.out.println(pad + "module " + m.getName()); case ModuleNode m -> {
for (ImportNode imp : m.getImports()) { System.out.println(pad + "module " + m.name());
for (ImportNode imp : m.imports()) {
System.out.println(pad + " import " + imp.moduleName()); System.out.println(pad + " import " + imp.moduleName());
} }
for (FunctionNode fn : m.getFunctions()) { for (FunctionNode fn : m.functions()) {
print(fn, indent + 1); print(fn, indent + 1);
} }
}
} else if (n instanceof FunctionNode f) { case FunctionNode(
System.out.println(pad + "function " + f.name() String name, List<ParameterNode> parameters, String returnType, List<StatementNode> body
+ "(params=" + f.parameters() + ", return=" + f.returnType() + ")"); ) -> {
for (StatementNode stmt : f.body()) { System.out.println(pad + "function " + name
+ "(params=" + parameters + ", return=" + returnType + ")");
for (StatementNode stmt : body) {
print(stmt, indent + 1); print(stmt, indent + 1);
} }
}
} else if (n instanceof DeclarationNode d) { case DeclarationNode d -> {
String init = d.getInitializer() String init = d.getInitializer()
.map(Object::toString) .map(Object::toString)
.map(s -> " = " + s) .map(s -> " = " + s)
.orElse(""); .orElse("");
System.out.println(pad + "declare " + d.getName() + ":" + d.getType() + init); System.out.println(pad + "declare " + d.getName() + ":" + d.getType() + init);
}
} else if (n instanceof AssignmentNode a) { case AssignmentNode(String variable, ExpressionNode value) ->
System.out.println(pad + a.variable() + " = " + a.value()); System.out.println(pad + variable + " = " + value);
case IfNode(ExpressionNode condition, List<StatementNode> thenBranch) -> {
} else if (n instanceof IfNode i) { System.out.println(pad + "if " + condition);
System.out.println(pad + "if " + i.condition()); for (StatementNode stmt : thenBranch) {
for (StatementNode stmt : i.thenBranch()) {
print(stmt, indent + 1); print(stmt, indent + 1);
} }
}
} else if (n instanceof LoopNode l) { case LoopNode(
StatementNode initializer, ExpressionNode condition, StatementNode update, List<StatementNode> body
) -> {
System.out.println(pad + "loop {"); System.out.println(pad + "loop {");
print(l.initializer(), indent + 1); print(initializer, indent + 1);
System.out.println(pad + " condition: " + l.condition()); System.out.println(pad + " condition: " + condition);
System.out.println(pad + " update: " + l.update()); System.out.println(pad + " update: " + update);
System.out.println(pad + " body {"); System.out.println(pad + " body {");
for (StatementNode stmt : l.body()) { for (StatementNode stmt : body) {
print(stmt, indent + 2); print(stmt, indent + 2);
} }
System.out.println(pad + " }"); System.out.println(pad + " }");
System.out.println(pad + "}"); System.out.println(pad + "}");
}
} else if (n instanceof ReturnNode r) { case ReturnNode r -> System.out.println(pad + "return" +
System.out.println(pad + "return" +
r.getExpression().map(e -> " " + e).orElse("")); r.getExpression().map(e -> " " + e).orElse(""));
case ExpressionStatementNode(ExpressionNode expression) -> System.out.println(pad + expression);
} else if (n instanceof ExpressionStatementNode es) { case null, default ->
System.out.println(pad + es.expression());
} else {
// 回退直接调用 toString() // 回退直接调用 toString()
System.out.println(pad + n); System.out.println(pad + n);
} }

View File

@ -3,20 +3,8 @@ package org.jcnc.snow.compiler.parser.ast;
/** /**
* 二元运算表达式节点 a + b * 二元运算表达式节点 a + b
*/ */
public class BinaryExpressionNode implements ExpressionNode { public record BinaryExpressionNode(ExpressionNode left, String operator,
private final ExpressionNode left; ExpressionNode right) implements ExpressionNode {
private final String operator;
private final ExpressionNode right;
public BinaryExpressionNode(ExpressionNode left, String operator, ExpressionNode right) {
this.left = left;
this.operator = operator;
this.right = right;
}
public ExpressionNode getLeft() { return left; }
public String getOperator() { return operator; }
public ExpressionNode getRight() { return right; }
@Override @Override
public String toString() { public String toString() {

View File

@ -7,28 +7,7 @@ import java.util.StringJoiner;
/** /**
* 模块定义节点包含模块名import 列表和函数列表 * 模块定义节点包含模块名import 列表和函数列表
*/ */
public class ModuleNode implements Node { public record ModuleNode(String name, List<ImportNode> imports, List<FunctionNode> functions) implements Node {
private final String name;
private final List<ImportNode> imports;
private final List<FunctionNode> functions;
public ModuleNode(String name, List<ImportNode> imports, List<FunctionNode> functions) {
this.name = name;
this.imports = imports;
this.functions = functions;
}
public String getName() {
return name;
}
public List<ImportNode> getImports() {
return imports;
}
public List<FunctionNode> getFunctions() {
return functions;
}
/** /**
* 返回模块的字符串表示便于调试和打印 * 返回模块的字符串表示便于调试和打印