From 6d835b1655223dccc58c489e4a92423e6f808ab9 Mon Sep 17 00:00:00 2001 From: luke Date: Mon, 9 Jun 2025 00:30:03 +0800 Subject: [PATCH 01/12] =?UTF-8?q?bug:=20=E4=BF=AE=E5=A4=8D=20CallExpressio?= =?UTF-8?q?nNode=20=E7=BC=BA=E5=A4=B1=E8=A1=8C=E5=8F=B7=E5=92=8C=E5=88=97?= =?UTF-8?q?=E5=8F=B7=E8=B7=9F=E8=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../compiler/parser/ast/CallExpressionNode.java | 16 +++++++++++++++- .../compiler/parser/expression/CallParselet.java | 12 +++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/CallExpressionNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/CallExpressionNode.java index c9109a1..089319f 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/ast/CallExpressionNode.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/CallExpressionNode.java @@ -14,7 +14,12 @@ import java.util.List; * @param callee 被调用的表达式节点,通常为函数标识符或成员访问表达式。 * @param arguments 参数表达式列表,依照调用顺序排列。 */ -public record CallExpressionNode(ExpressionNode callee, List arguments) implements ExpressionNode { +public record CallExpressionNode( + ExpressionNode callee, + List arguments, + int line, // 添加行号 + int column // 添加列号 +) implements ExpressionNode { /** * 返回函数调用表达式的字符串形式。 @@ -36,4 +41,13 @@ public record CallExpressionNode(ExpressionNode callee, List arg sb.append(")"); return sb.toString(); } + + // Getter方法用于访问行号和列号 + public int line() { + return line; + } + + public int column() { + return column; + } } diff --git a/src/main/java/org/jcnc/snow/compiler/parser/expression/CallParselet.java b/src/main/java/org/jcnc/snow/compiler/parser/expression/CallParselet.java index 4e8d3a3..eb47b86 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/expression/CallParselet.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/expression/CallParselet.java @@ -12,8 +12,7 @@ import java.util.List; * {@code CallParselet} 表示函数调用语法的中缀解析器。 *

* 用于处理形如 {@code foo(arg1, arg2)} 的函数调用结构。 - * 在 Pratt 解析器架构中,该解析器在函数名之后接收括号开始的调用参数, - * 构建 {@link CallExpressionNode} 抽象语法树节点。 + * 在 Pratt 解析器架构中,该解析器在函数名之后接收括号开始的调用参数,构建 {@link CallExpressionNode} 抽象语法树节点。 *

*/ public class CallParselet implements InfixParselet { @@ -31,6 +30,11 @@ public class CallParselet implements InfixParselet { List args = new ArrayList<>(); + // 获取当前 token 的行号和列号 + int line = ctx.getTokens().peek().getLine(); + int column = ctx.getTokens().peek().getCol(); + + // 解析函数调用参数 if (!ctx.getTokens().peek().getLexeme().equals(")")) { do { args.add(new PrattExpressionParser().parse(ctx)); @@ -38,7 +42,9 @@ public class CallParselet implements InfixParselet { } ctx.getTokens().expect(")"); // 消费并验证 ")" - return new CallExpressionNode(left, args); + + // 创建 CallExpressionNode 并传递位置信息 + return new CallExpressionNode(left, args, line, column); } /** From 46e3f6d6e96745525eceda7e71627a3ac892f784 Mon Sep 17 00:00:00 2001 From: luke Date: Mon, 9 Jun 2025 00:39:31 +0800 Subject: [PATCH 02/12] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../parser/ast/CallExpressionNode.java | 45 +++++++++++-------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/CallExpressionNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/CallExpressionNode.java index 089319f..593658e 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/ast/CallExpressionNode.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/CallExpressionNode.java @@ -7,46 +7,55 @@ import java.util.List; /** * {@code CallExpressionNode} 表示抽象语法树(AST)中的函数调用表达式节点。 *

- * 函数调用表达式用于表示函数或过程的调用操作, - * 包括被调用对象(callee)以及一组参数表达式(arguments)。 + * 函数调用表达式用于表示函数或过程的调用操作,包含被调用对象(callee)以及一组参数表达式(arguments)。 *

* - * @param callee 被调用的表达式节点,通常为函数标识符或成员访问表达式。 - * @param arguments 参数表达式列表,依照调用顺序排列。 + * @param callee 被调用的表达式节点,通常为函数标识符或成员访问表达式,表示函数名或方法名等。 + * @param arguments 参数表达式列表,表示函数调用中传递给函数的实际参数。参数的顺序与调用顺序一致。 + * @param line 当前表达式所在的行号,方便调试和错误定位。 + * @param column 当前表达式所在的列号,用于精确定位错误位置。 */ public record CallExpressionNode( - ExpressionNode callee, - List arguments, - int line, // 添加行号 - int column // 添加列号 + ExpressionNode callee, // 被调用的表达式节点,表示函数或方法名 + List arguments, // 函数调用的参数表达式列表 + int line, // 当前节点所在的行号 + int column // 当前节点所在的列号 ) implements ExpressionNode { /** - * 返回函数调用表达式的字符串形式。 + * 返回函数调用表达式的字符串形式,便于调试与语法树可视化。 *

- * 该格式将输出为类似 {@code foo(a, b, c)} 的形式, - * 便于调试与语法树可视化。 + * 该方法将表达式节点转化为类似 {@code foo(a, b, c)} 的格式,便于查看和理解抽象语法树的结构。 *

* - * @return 表示函数调用的字符串表示 + * @return 表示函数调用的字符串表示,格式为 {@code callee(arguments)}。 */ @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append(callee).append("("); + sb.append(callee).append("("); // 拼接函数名和左括号 for (int i = 0; i < arguments.size(); i++) { - sb.append(arguments.get(i)); - if (i + 1 < arguments.size()) sb.append(", "); + sb.append(arguments.get(i)); // 拼接每个参数 + if (i + 1 < arguments.size()) sb.append(", "); // 如果不是最后一个参数,添加逗号和空格 } - sb.append(")"); - return sb.toString(); + sb.append(")"); // 拼接右括号 + return sb.toString(); // 返回拼接好的字符串 } - // Getter方法用于访问行号和列号 + /** + * 获取当前表达式所在的行号。 + * + * @return 当前表达式的行号。 + */ public int line() { return line; } + /** + * 获取当前表达式所在的列号。 + * + * @return 当前表达式的列号。 + */ public int column() { return column; } From f356bcf227c267082d143275454587d95fc01bfd Mon Sep 17 00:00:00 2001 From: Luke Date: Mon, 9 Jun 2025 14:39:58 +0800 Subject: [PATCH 03/12] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E8=AF=AD?= =?UTF-8?q?=E4=B9=89=E9=94=99=E8=AF=AF=E5=AE=9A=E4=BD=8D=E5=88=B0=E5=85=B7?= =?UTF-8?q?=E4=BD=93=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jcnc/snow/compiler/cli/SnowCompiler.java | 2 +- .../parser/ast/CallExpressionNode.java | 10 +++- .../parser/context/ParserContext.java | 27 ++++++++-- .../parser/expression/CallParselet.java | 5 +- .../semantic/error/SemanticError.java | 51 +++++++++++++++---- 5 files changed, 79 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/jcnc/snow/compiler/cli/SnowCompiler.java b/src/main/java/org/jcnc/snow/compiler/cli/SnowCompiler.java index 6c2b335..fa0831a 100644 --- a/src/main/java/org/jcnc/snow/compiler/cli/SnowCompiler.java +++ b/src/main/java/org/jcnc/snow/compiler/cli/SnowCompiler.java @@ -59,7 +59,7 @@ public class SnowCompiler { System.out.println(code); LexerEngine lexer = new LexerEngine(code, p.toString()); - ParserContext ctx = new ParserContext(lexer.getAllTokens()); + ParserContext ctx = new ParserContext(lexer.getAllTokens(), p.toString()); allAst.addAll(new ParserEngine(ctx).parse()); } diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/CallExpressionNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/CallExpressionNode.java index 593658e..ac36871 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/ast/CallExpressionNode.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/CallExpressionNode.java @@ -19,7 +19,8 @@ public record CallExpressionNode( ExpressionNode callee, // 被调用的表达式节点,表示函数或方法名 List arguments, // 函数调用的参数表达式列表 int line, // 当前节点所在的行号 - int column // 当前节点所在的列号 + int column, // 当前节点所在的列号 + String file // 当前节点所在的文件 ) implements ExpressionNode { /** @@ -59,4 +60,11 @@ public record CallExpressionNode( public int column() { return column; } + + /** + * 获取当前表达式所在的文件名。 + * + * @return 当前表达式所在的文件名。 + */ + public String file() { return file; } } diff --git a/src/main/java/org/jcnc/snow/compiler/parser/context/ParserContext.java b/src/main/java/org/jcnc/snow/compiler/parser/context/ParserContext.java index bbf2b2e..a3d1481 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/context/ParserContext.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/context/ParserContext.java @@ -16,15 +16,27 @@ public class ParserContext { /** 当前语法分析所使用的 Token 流 */ private final TokenStream tokens; + /** 当前语法分析所使用的资源文件名 */ + private final String sourceName; + + /** - * 使用词法分析得到的 Token 列表构造上下文。 + * 构造一个新的 {@code ParserContext} 实例,用于在语法分析阶段传递上下文信息。 + *

+ * 本构造方法接收词法分析得到的 {@link Token} 列表以及当前源文件名,
+ * 并将 Token 列表包装为 {@link TokenStream} 以便后续遍历与分析。
+ * 源文件名通常用于错误定位、调试和报错信息中指明具体文件。 + *

* - * @param tokens 词法分析器生成的 Token 集合 + * @param tokens 词法分析器生成的 Token 集合,表示待解析的完整源代码流 + * @param sourceName 当前正在解析的源文件名(或文件路径),用于错误报告和调试定位 */ - public ParserContext(List tokens) { + public ParserContext(List tokens, String sourceName) { this.tokens = new TokenStream(tokens); + this.sourceName = sourceName; } + /** * 获取封装的 Token 流,用于驱动语法分析过程。 * @@ -33,4 +45,13 @@ public class ParserContext { public TokenStream getTokens() { return tokens; } + + /** + * 获取资源文件名,用于发现错误后展示文件名。 + * + * @return 当前语法分析所使用的资源文件名 + */ + public String getSourceName() { + return sourceName; + } } \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/compiler/parser/expression/CallParselet.java b/src/main/java/org/jcnc/snow/compiler/parser/expression/CallParselet.java index eb47b86..9499f6d 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/expression/CallParselet.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/expression/CallParselet.java @@ -43,8 +43,9 @@ public class CallParselet implements InfixParselet { ctx.getTokens().expect(")"); // 消费并验证 ")" - // 创建 CallExpressionNode 并传递位置信息 - return new CallExpressionNode(left, args, line, column); + // 创建 CallExpressionNode 并传递位置信息,文件名称 + String file = ctx.getSourceName(); + return new CallExpressionNode(left, args, line, column, file); } /** diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/error/SemanticError.java b/src/main/java/org/jcnc/snow/compiler/semantic/error/SemanticError.java index 121d0eb..a564054 100644 --- a/src/main/java/org/jcnc/snow/compiler/semantic/error/SemanticError.java +++ b/src/main/java/org/jcnc/snow/compiler/semantic/error/SemanticError.java @@ -1,32 +1,65 @@ package org.jcnc.snow.compiler.semantic.error; - import org.jcnc.snow.compiler.parser.ast.base.Node; /** - * 表示一次语义错误。
+ * 表示一次语义错误(Semantic Error)。 + *

+ * 本类用于在语义分析阶段记录出错的 AST 节点及对应的错误信息,
+ * 便于后续错误报告、调试和 IDE 集成等多种用途。 + *

*
    - *
  • 记录对应 {@link Node} 及出错信息;
  • - *
  • 重写 {@link #toString()},以 行 X, 列 Y: message 格式输出,
  • - *
  • 避免默认的 Node@hash 形式。
  • + *
  • 通过关联的 {@link Node} 提供出错的具体位置(文件、行号、列号等)信息;
  • + *
  • 支持格式化错误输出,友好展示错误发生的上下文;
  • + *
  • 避免直接输出 AST 节点的默认 toString() 形式。
  • *
+ * + *

示例输出:

+ *
+ *   playground\main.snow: 行 7, 列 28: 参数类型不匹配 (位置 1): 期望 int, 实际 long
+ * 
+ * + * @param node 指向发生语义错误的 AST 节点,可用于获取详细的位置信息(文件名、行号、列号等) + * @param message 描述该语义错误的详细信息,通常为人类可读的解释或修正建议 + * */ public record SemanticError(Node node, String message) { + /** + * 返回该语义错误的字符串描述,格式如下: + *
+     * [文件名: ]行 X, 列 Y: [错误信息]
+     * 
+ * 若节点未能提供有效位置,则输出“未知位置”。 + * + * @return 适合用户阅读的语义错误描述字符串 + */ @Override public String toString() { // Node 假定提供 line() / column() 方法;如无则返回 -1 int line = -1; int col = -1; + String file = null; + if (node != null) { try { line = (int) node.getClass().getMethod("line").invoke(node); + } catch (Exception ignored) { + } + try { col = (int) node.getClass().getMethod("column").invoke(node); - } catch (ReflectiveOperationException ignored) { - // 若 Node 未提供 line/column 方法则保持 -1 + } catch (Exception ignored) { + } + try { + file = (String) node.getClass().getMethod("file").invoke(node); + } catch (Exception ignored) { } } - String pos = (line >= 0 && col >= 0) ? ("行 " + line + ", 列 " + col) : "未知位置"; - return pos + ": " + message; + + StringBuilder sb = new StringBuilder(); + if (file != null && !file.isBlank()) sb.append(file).append(": "); + sb.append((line >= 0 && col >= 0) ? "行 " + line + ", 列 " + col : "未知位置"); + sb.append(": ").append(message); + return sb.toString(); } } From 8d628d29d2b0a5703badb83f3c1d23e74d2bb7bd Mon Sep 17 00:00:00 2001 From: Luke Date: Mon, 9 Jun 2025 14:55:24 +0800 Subject: [PATCH 04/12] =?UTF-8?q?feat:=20=E8=AF=AD=E4=B9=89=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E5=AE=9A=E4=BD=8D=E4=B8=BA=E7=BB=9D=E5=AF=B9=E8=B7=AF?= =?UTF-8?q?=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/jcnc/snow/compiler/parser/context/ParserContext.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jcnc/snow/compiler/parser/context/ParserContext.java b/src/main/java/org/jcnc/snow/compiler/parser/context/ParserContext.java index a3d1481..5ff228a 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/context/ParserContext.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/context/ParserContext.java @@ -1,6 +1,8 @@ package org.jcnc.snow.compiler.parser.context; import org.jcnc.snow.compiler.lexer.token.Token; + +import java.nio.file.Paths; import java.util.List; /** @@ -33,7 +35,7 @@ public class ParserContext { */ public ParserContext(List tokens, String sourceName) { this.tokens = new TokenStream(tokens); - this.sourceName = sourceName; + this.sourceName = Paths.get(sourceName).toAbsolutePath().toString(); } From bd96f76240f30b3bdd31d62df3d32da540caa624 Mon Sep 17 00:00:00 2001 From: Luke Date: Mon, 9 Jun 2025 14:57:59 +0800 Subject: [PATCH 05/12] =?UTF-8?q?docs:=20=E4=BF=AE=E6=94=B9=E8=AF=AD?= =?UTF-8?q?=E4=B9=89=E9=94=99=E8=AF=AF=E5=AE=9A=E4=BD=8D=E4=B8=BA=E7=BB=9D?= =?UTF-8?q?=E5=AF=B9=E8=B7=AF=E5=BE=84=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/jcnc/snow/compiler/semantic/error/SemanticError.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/error/SemanticError.java b/src/main/java/org/jcnc/snow/compiler/semantic/error/SemanticError.java index a564054..4a36d25 100644 --- a/src/main/java/org/jcnc/snow/compiler/semantic/error/SemanticError.java +++ b/src/main/java/org/jcnc/snow/compiler/semantic/error/SemanticError.java @@ -16,7 +16,7 @@ import org.jcnc.snow.compiler.parser.ast.base.Node; * *

示例输出:

*
- *   playground\main.snow: 行 7, 列 28: 参数类型不匹配 (位置 1): 期望 int, 实际 long
+ *   D:\Devs\IdeaProjects\Snow\playground\main.snow: 行 7, 列 28: 参数类型不匹配 (位置 1): 期望 int, 实际 long
  * 
* * @param node 指向发生语义错误的 AST 节点,可用于获取详细的位置信息(文件名、行号、列号等) @@ -28,7 +28,7 @@ public record SemanticError(Node node, String message) { /** * 返回该语义错误的字符串描述,格式如下: *
-     * [文件名: ]行 X, 列 Y: [错误信息]
+     * [文件绝对路径: ]行 X, 列 Y: [错误信息]
      * 
* 若节点未能提供有效位置,则输出“未知位置”。 * From 94c2a34fd684d1f06ca283eaa794b28a8fe39dee Mon Sep 17 00:00:00 2001 From: Luke Date: Mon, 9 Jun 2025 17:17:46 +0800 Subject: [PATCH 06/12] =?UTF-8?q?style:=20=E4=BB=A3=E7=A0=81=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- playground/{main.snow => Main.snow} | 0 playground/{test.snow => Math.snow} | 2 +- .../java/org/jcnc/snow/compiler/lexer/core/LexerEngine.java | 2 +- .../org/jcnc/snow/compiler/semantic/error/SemanticError.java | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename playground/{main.snow => Main.snow} (100%) rename playground/{test.snow => Math.snow} (86%) diff --git a/playground/main.snow b/playground/Main.snow similarity index 100% rename from playground/main.snow rename to playground/Main.snow diff --git a/playground/test.snow b/playground/Math.snow similarity index 86% rename from playground/test.snow rename to playground/Math.snow index 161b7b2..e79d078 100644 --- a/playground/test.snow +++ b/playground/Math.snow @@ -2,7 +2,7 @@ module: Math function: factorial parameter: declare n1: long - declare n2: long + declare n2: int return_type: long body: return n1+n2 diff --git a/src/main/java/org/jcnc/snow/compiler/lexer/core/LexerEngine.java b/src/main/java/org/jcnc/snow/compiler/lexer/core/LexerEngine.java index 819fa07..4d06999 100644 --- a/src/main/java/org/jcnc/snow/compiler/lexer/core/LexerEngine.java +++ b/src/main/java/org/jcnc/snow/compiler/lexer/core/LexerEngine.java @@ -48,7 +48,7 @@ public class LexerEngine { * 构造时立即进行全量扫描。 * * @param source 源代码文本 - * @param sourceName 文件名或来源描述(如"main.snow") + * @param sourceName 文件名或来源描述(如"Main.snow") */ public LexerEngine(String source, String sourceName) { this.context = new LexerContext(source); diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/error/SemanticError.java b/src/main/java/org/jcnc/snow/compiler/semantic/error/SemanticError.java index 4a36d25..113777e 100644 --- a/src/main/java/org/jcnc/snow/compiler/semantic/error/SemanticError.java +++ b/src/main/java/org/jcnc/snow/compiler/semantic/error/SemanticError.java @@ -16,7 +16,7 @@ import org.jcnc.snow.compiler.parser.ast.base.Node; * *

示例输出:

*
- *   D:\Devs\IdeaProjects\Snow\playground\main.snow: 行 7, 列 28: 参数类型不匹配 (位置 1): 期望 int, 实际 long
+ *   D:\Devs\IdeaProjects\Snow\playground\Main.snow: 行 7, 列 28: 参数类型不匹配 (位置 1): 期望 int, 实际 long
  * 
* * @param node 指向发生语义错误的 AST 节点,可用于获取详细的位置信息(文件名、行号、列号等) From 8081f12658d55c25750f2221ae3edd31211cc074 Mon Sep 17 00:00:00 2001 From: luke Date: Mon, 9 Jun 2025 21:04:18 +0800 Subject: [PATCH 07/12] =?UTF-8?q?docs:=20=E4=BF=AE=E5=A4=8D=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 52d4e39..c8e0717 100644 --- a/README.md +++ b/README.md @@ -8,22 +8,22 @@

- + - +

- + - + - +

From 5106830b989b79db45a02b66c285d6c738071ba7 Mon Sep 17 00:00:00 2001 From: luke Date: Mon, 9 Jun 2025 21:09:30 +0800 Subject: [PATCH 08/12] =?UTF-8?q?docs:=20=E5=88=A0=E9=99=A4=E6=97=A0?= =?UTF-8?q?=E5=85=B3=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/jcnc/snow/compiler/parser/core/ParserEngine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/jcnc/snow/compiler/parser/core/ParserEngine.java b/src/main/java/org/jcnc/snow/compiler/parser/core/ParserEngine.java index 03810b5..7d0854f 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/core/ParserEngine.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/core/ParserEngine.java @@ -17,7 +17,7 @@ public record ParserEngine(ParserContext ctx) { List errs = new ArrayList<>(); TokenStream ts = ctx.getTokens(); - while (ts.isAtEnd()) { // ← 取反 + while (ts.isAtEnd()) { // 跳过空行 if (ts.peek().getType() == TokenType.NEWLINE) { ts.next(); From cd72761908d8d7f50357bf3b82ca3b8c6f0c53ad Mon Sep 17 00:00:00 2001 From: luke Date: Mon, 9 Jun 2025 21:10:06 +0800 Subject: [PATCH 09/12] =?UTF-8?q?bug:=20=E5=85=81=E8=AE=B8=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=9B=B4=E6=8E=A5=E4=BB=A5=20EOF=20=E7=BB=93=E6=9D=9F?= =?UTF-8?q?=20`end=20module`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/jcnc/snow/compiler/parser/module/ModuleParser.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/jcnc/snow/compiler/parser/module/ModuleParser.java b/src/main/java/org/jcnc/snow/compiler/parser/module/ModuleParser.java index 02ada73..b696410 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/module/ModuleParser.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/module/ModuleParser.java @@ -88,9 +88,8 @@ public class ModuleParser implements TopLevelParser { // 确保模块体以 "end module" 结束 ts.expect("end"); ts.expect("module"); - ts.expectType(TokenType.NEWLINE); // 构建并返回完整的模块语法树节点 return new ModuleNode(name, imports, functions); } -} +} \ No newline at end of file From d940e26a0cf1dda1fc1f2372224f672c1092080a Mon Sep 17 00:00:00 2001 From: Luke Date: Tue, 10 Jun 2025 09:50:58 +0800 Subject: [PATCH 10/12] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=20ASTJsonSerial?= =?UTF-8?q?izer=20=E4=B8=AD=20CallExpressionNode=20=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E5=8C=B9=E9=85=8D=E5=8F=82=E6=95=B0=E6=95=B0=E9=87=8F=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E7=9A=84=E7=BC=96=E8=AF=91=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jcnc/snow/compiler/parser/utils/ASTJsonSerializer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/jcnc/snow/compiler/parser/utils/ASTJsonSerializer.java b/src/main/java/org/jcnc/snow/compiler/parser/utils/ASTJsonSerializer.java index df36075..87dc160 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/utils/ASTJsonSerializer.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/utils/ASTJsonSerializer.java @@ -182,7 +182,7 @@ public class ASTJsonSerializer { case IdentifierNode(String name) -> exprMap("Identifier", "name", name); case NumberLiteralNode(String value) -> exprMap("NumberLiteral", "value", value); case StringLiteralNode(String value) -> exprMap("StringLiteral", "value", value); - case CallExpressionNode(ExpressionNode callee, List arguments) -> { + case CallExpressionNode(ExpressionNode callee, List arguments, int line, int column, String file) -> { List args = new ArrayList<>(arguments.size()); for (ExpressionNode arg : arguments) args.add(exprToMap(arg)); yield exprMap("CallExpression", "callee", exprToMap(callee), "arguments", args); @@ -195,4 +195,4 @@ public class ASTJsonSerializer { default -> Map.of("type", expr.getClass().getSimpleName()); }; } -} +} \ No newline at end of file From f2c07175d6cbc3a40f062dc144f62f10cfe7959e Mon Sep 17 00:00:00 2001 From: Luke Date: Tue, 10 Jun 2025 09:52:22 +0800 Subject: [PATCH 11/12] =?UTF-8?q?style:=20snow=E4=BB=A3=E7=A0=81=E6=81=A2?= =?UTF-8?q?=E5=A4=8D=E4=B8=BA=E6=AD=A3=E5=B8=B8=E7=BC=96=E8=AF=91=E7=9A=84?= =?UTF-8?q?=E6=AD=A3=E7=A1=AE=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- playground/Math.snow | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playground/Math.snow b/playground/Math.snow index e79d078..161b7b2 100644 --- a/playground/Math.snow +++ b/playground/Math.snow @@ -2,7 +2,7 @@ module: Math function: factorial parameter: declare n1: long - declare n2: int + declare n2: long return_type: long body: return n1+n2 From b8f35a1c71a488cbac78fed1ae4056b633ef84e0 Mon Sep 17 00:00:00 2001 From: Luke Date: Tue, 10 Jun 2025 09:53:14 +0800 Subject: [PATCH 12/12] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0v0.1.1=E7=9A=84?= =?UTF-8?q?=E5=BE=BD=E7=AB=A0=E5=92=8C=E5=88=A0=E9=99=A4=E5=86=97=E4=BD=99?= =?UTF-8?q?=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c8e0717..f0d9cd6 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@

Snow编程语言

-star -fork +star +fork

@@ -12,7 +12,7 @@ - +

@@ -68,9 +68,9 @@ Snow 语言受到 LLM 驱动代码生成趋势的启发,强调简单而清晰的 3. **运行项目** - 使用IDEA配置好的运行配置SnowCompiler + 使用IDEA配置好的运行配置SnowCompiler - ![IMG_运行配置文件_1.png](doc/README/IMG/IMG_Run-Profile_1.png) + ![IMG_运行配置文件_1.png](doc/README/IMG/IMG_Run-Profile_1.png) 4. **运行成功** @@ -243,7 +243,7 @@ Process has ended 3: 0 ``` - + ## 编译Snow源代码 @@ -329,8 +329,6 @@ end module [Git 管理规范](doc/Git-Management/Git-Management.md) - - ## 开发计划 / TODO * 扩展标准库支持和更多内置模块,如字符串,文件操作等常用功能。