使用纪录类

This commit is contained in:
Luke 2025-04-22 21:57:02 +08:00
parent 8d1b180c2d
commit 157f1e2f11
49 changed files with 63 additions and 244 deletions

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/JsonFormatter.java
package org.jcnc.snow.compiler;
public class JsonFormatter {

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ParserEngine.java
package org.jcnc.snow.compiler.parser;
import org.jcnc.snow.compiler.lexer.token.TokenType;
@ -23,7 +22,7 @@ public class ParserEngine {
public List<Node> parse() {
List<Node> nodes = new ArrayList<>();
TokenStream ts = ctx.getTokens();
while (!ts.isAtEnd()) {
while (ts.isAtEnd()) {
// 跳过空行NEWLINE
if (ts.peek().getType() == TokenType.NEWLINE) {
ts.next();

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/TopLevelParser.java
package org.jcnc.snow.compiler.parser;
import org.jcnc.snow.compiler.parser.context.ParserContext;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/ASTJsonSerializer.java
package org.jcnc.snow.compiler.parser.ast;
import java.util.List;
@ -39,7 +38,7 @@ public class ASTJsonSerializer {
for (int i = 0; i < m.getImports().size(); i++) {
ImportNode imp = m.getImports().get(i);
sb.append("{\"type\":\"Import\",\"module\":")
.append(quote(imp.getModuleName())).append("}");
.append(quote(imp.moduleName())).append("}");
if (i + 1 < m.getImports().size()) sb.append(",");
}
sb.append("],");
@ -56,20 +55,20 @@ public class ASTJsonSerializer {
private static String functionToJson(FunctionNode f) {
StringBuilder sb = new StringBuilder();
sb.append("{\"type\":\"Function\",")
.append("\"name\":").append(quote(f.getName())).append(",");
.append("\"name\":").append(quote(f.name())).append(",");
// parameters
sb.append("\"parameters\":[");
for (int i = 0; i < f.getParameters().size(); i++) {
ParameterNode p = f.getParameters().get(i);
sb.append("{\"name\":").append(quote(p.getName()))
.append(",\"type\":").append(quote(p.getType())).append("}");
if (i + 1 < f.getParameters().size()) sb.append(",");
for (int i = 0; i < f.parameters().size(); i++) {
ParameterNode p = f.parameters().get(i);
sb.append("{\"name\":").append(quote(p.name()))
.append(",\"type\":").append(quote(p.type())).append("}");
if (i + 1 < f.parameters().size()) sb.append(",");
}
sb.append("],");
sb.append("\"returnType\":").append(quote(f.getReturnType())).append(",");
sb.append("\"returnType\":").append(quote(f.returnType())).append(",");
// body
sb.append("\"body\":[");
List<StatementNode> body = f.getBody();
List<StatementNode> body = f.body();
for (int i = 0; i < body.size(); i++) {
sb.append(nodeToJson(body.get(i)));
if (i + 1 < body.size()) sb.append(",");
@ -92,18 +91,18 @@ public class ASTJsonSerializer {
private static String assignmentToJson(AssignmentNode a) {
return "{\"type\":\"Assignment\",\"variable\":"
+ quote(a.getVariable())
+ quote(a.variable())
+ ",\"value\":"
+ exprToJson(a.getValue())
+ exprToJson(a.value())
+ "}";
}
private static String ifToJson(IfNode i) {
StringBuilder sb = new StringBuilder();
sb.append("{\"type\":\"If\",\"condition\":")
.append(exprToJson(i.getCondition())).append(",");
.append(exprToJson(i.condition())).append(",");
sb.append("\"then\":[");
List<StatementNode> thenBranch = i.getThenBranch();
List<StatementNode> thenBranch = i.thenBranch();
for (int j = 0; j < thenBranch.size(); j++) {
sb.append(nodeToJson(thenBranch.get(j)));
if (j + 1 < thenBranch.size()) sb.append(",");
@ -115,11 +114,11 @@ public class ASTJsonSerializer {
private static String loopToJson(LoopNode l) {
StringBuilder sb = new StringBuilder();
sb.append("{\"type\":\"Loop\",")
.append("\"initializer\":").append(nodeToJson(l.getInitializer())).append(",")
.append("\"condition\":").append(exprToJson(l.getCondition())).append(",")
.append("\"update\":").append(nodeToJson(l.getUpdate())).append(",")
.append("\"initializer\":").append(nodeToJson(l.initializer())).append(",")
.append("\"condition\":").append(exprToJson(l.condition())).append(",")
.append("\"update\":").append(nodeToJson(l.update())).append(",")
.append("\"body\":[");
List<StatementNode> body = l.getBody();
List<StatementNode> body = l.body();
for (int i = 0; i < body.size(); i++) {
sb.append(nodeToJson(body.get(i)));
if (i + 1 < body.size()) sb.append(",");
@ -140,7 +139,7 @@ public class ASTJsonSerializer {
private static String exprStmtToJson(ExpressionStatementNode es) {
return "{\"type\":\"ExpressionStatement\",\"expression\":"
+ exprToJson(es.getExpression())
+ exprToJson(es.expression())
+ "}";
}
@ -163,30 +162,30 @@ public class ASTJsonSerializer {
+ "}";
}
private static String idToJson(IdentifierNode id) {
return "{\"type\":\"Identifier\",\"name\":" + quote(id.getName()) + "}";
return "{\"type\":\"Identifier\",\"name\":" + quote(id.name()) + "}";
}
private static String numToJson(NumberLiteralNode num) {
return "{\"type\":\"NumberLiteral\",\"value\":" + quote(num.getValue()) + "}";
return "{\"type\":\"NumberLiteral\",\"value\":" + quote(num.value()) + "}";
}
private static String strToJson(StringLiteralNode str) {
return "{\"type\":\"StringLiteral\",\"value\":" + quote(str.getValue()) + "}";
return "{\"type\":\"StringLiteral\",\"value\":" + quote(str.value()) + "}";
}
private static String callToJson(CallExpressionNode c) {
StringBuilder sb = new StringBuilder();
sb.append("{\"type\":\"CallExpression\",\"callee\":")
.append(exprToJson(c.getCallee())).append(",")
.append(exprToJson(c.callee())).append(",")
.append("\"arguments\":[");
for (int i = 0; i < c.getArguments().size(); i++) {
sb.append(exprToJson(c.getArguments().get(i)));
if (i + 1 < c.getArguments().size()) sb.append(",");
for (int i = 0; i < c.arguments().size(); i++) {
sb.append(exprToJson(c.arguments().get(i)));
if (i + 1 < c.arguments().size()) sb.append(",");
}
sb.append("]}");
return sb.toString();
}
private static String memberToJson(MemberExpressionNode m) {
return "{\"type\":\"MemberExpression\",\"object\":"
+ exprToJson(m.getObject())
+ ",\"member\":" + quote(m.getMember())
+ exprToJson(m.object())
+ ",\"member\":" + quote(m.member())
+ "}";
}

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/ASTPrinter.java
package org.jcnc.snow.compiler.parser.ast;
import java.util.List;
@ -19,16 +18,16 @@ public class ASTPrinter {
if (n instanceof ModuleNode m) {
System.out.println(pad + "module " + m.getName());
for (ImportNode imp : m.getImports()) {
System.out.println(pad + " import " + imp.getModuleName());
System.out.println(pad + " import " + imp.moduleName());
}
for (FunctionNode fn : m.getFunctions()) {
print(fn, indent + 1);
}
} else if (n instanceof FunctionNode f) {
System.out.println(pad + "function " + f.getName()
+ "(params=" + f.getParameters() + ", return=" + f.getReturnType() + ")");
for (StatementNode stmt : f.getBody()) {
System.out.println(pad + "function " + f.name()
+ "(params=" + f.parameters() + ", return=" + f.returnType() + ")");
for (StatementNode stmt : f.body()) {
print(stmt, indent + 1);
}
@ -40,21 +39,21 @@ public class ASTPrinter {
System.out.println(pad + "declare " + d.getName() + ":" + d.getType() + init);
} else if (n instanceof AssignmentNode a) {
System.out.println(pad + a.getVariable() + " = " + a.getValue());
System.out.println(pad + a.variable() + " = " + a.value());
} else if (n instanceof IfNode i) {
System.out.println(pad + "if " + i.getCondition());
for (StatementNode stmt : i.getThenBranch()) {
System.out.println(pad + "if " + i.condition());
for (StatementNode stmt : i.thenBranch()) {
print(stmt, indent + 1);
}
} else if (n instanceof LoopNode l) {
System.out.println(pad + "loop {");
print(l.getInitializer(), indent + 1);
System.out.println(pad + " condition: " + l.getCondition());
System.out.println(pad + " update: " + l.getUpdate());
print(l.initializer(), indent + 1);
System.out.println(pad + " condition: " + l.condition());
System.out.println(pad + " update: " + l.update());
System.out.println(pad + " body {");
for (StatementNode stmt : l.getBody()) {
for (StatementNode stmt : l.body()) {
print(stmt, indent + 2);
}
System.out.println(pad + " }");
@ -65,7 +64,7 @@ public class ASTPrinter {
r.getExpression().map(e -> " " + e).orElse(""));
} else if (n instanceof ExpressionStatementNode es) {
System.out.println(pad + es.getExpression());
System.out.println(pad + es.expression());
} else {
// 回退直接调用 toString()

View File

@ -1,25 +1,9 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/AssignmentNode.java
package org.jcnc.snow.compiler.parser.ast;
/**
* 赋值语句节点例如 x = expr
*/
public class AssignmentNode implements StatementNode {
private final String variable;
private final ExpressionNode value;
public AssignmentNode(String variable, ExpressionNode value) {
this.variable = variable;
this.value = value;
}
public String getVariable() {
return variable;
}
public ExpressionNode getValue() {
return value;
}
public record AssignmentNode(String variable, ExpressionNode value) implements StatementNode {
@Override
public String toString() {

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/BinaryExpressionNode.java
package org.jcnc.snow.compiler.parser.ast;
/**

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/CallExpressionNode.java
package org.jcnc.snow.compiler.parser.ast;
import java.util.List;
@ -6,17 +5,7 @@ import java.util.List;
/**
* 函数调用表达式节点callee(args)
*/
public class CallExpressionNode implements ExpressionNode {
private final ExpressionNode callee;
private final List<ExpressionNode> arguments;
public CallExpressionNode(ExpressionNode callee, List<ExpressionNode> arguments) {
this.callee = callee;
this.arguments = arguments;
}
public ExpressionNode getCallee() { return callee; }
public List<ExpressionNode> getArguments() { return arguments; }
public record CallExpressionNode(ExpressionNode callee, List<ExpressionNode> arguments) implements ExpressionNode {
@Override
public String toString() {

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/DeclarationNode.java
package org.jcnc.snow.compiler.parser.ast;
import java.util.Optional;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/ExpressionNode.java
package org.jcnc.snow.compiler.parser.ast;
/**

View File

@ -1,15 +1,7 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/ExpressionStatementNode.java
package org.jcnc.snow.compiler.parser.ast;
/**
* 单独的表达式语句节点如函数调用赋值等
*/
public class ExpressionStatementNode implements StatementNode {
private final ExpressionNode expression;
public ExpressionStatementNode(ExpressionNode expression) {
this.expression = expression;
}
public ExpressionNode getExpression() { return expression; }
public record ExpressionStatementNode(ExpressionNode expression) implements StatementNode {
}

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/FunctionNode.java
package org.jcnc.snow.compiler.parser.ast;
import java.util.List;
@ -6,22 +5,6 @@ import java.util.List;
/**
* 函数定义节点包含函数名参数列表返回类型和函数体语句列表
*/
public class FunctionNode implements Node {
private final String name;
private final List<ParameterNode> parameters;
private final String returnType;
private final List<StatementNode> body;
public FunctionNode(String name, List<ParameterNode> parameters,
String returnType, List<StatementNode> body) {
this.name = name;
this.parameters = parameters;
this.returnType = returnType;
this.body = body;
}
public String getName() { return name; }
public List<ParameterNode> getParameters() { return parameters; }
public String getReturnType() { return returnType; }
public List<StatementNode> getBody() { return body; }
public record FunctionNode(String name, List<ParameterNode> parameters, String returnType,
List<StatementNode> body) implements Node {
}

View File

@ -1,17 +1,9 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/IdentifierNode.java
package org.jcnc.snow.compiler.parser.ast;
/**
* 标识符表达式节点
*/
public class IdentifierNode implements ExpressionNode {
private final String name;
public IdentifierNode(String name) {
this.name = name;
}
public String getName() { return name; }
public record IdentifierNode(String name) implements ExpressionNode {
@Override
public String toString() {
return name;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/IfNode.java
package org.jcnc.snow.compiler.parser.ast;
import java.util.List;
@ -6,15 +5,5 @@ import java.util.List;
/**
* if 语句节点包含条件表达式和 then 分支语句列表
*/
public class IfNode implements StatementNode {
private final ExpressionNode condition;
private final List<StatementNode> thenBranch;
public IfNode(ExpressionNode condition, List<StatementNode> thenBranch) {
this.condition = condition;
this.thenBranch = thenBranch;
}
public ExpressionNode getCondition() { return condition; }
public List<StatementNode> getThenBranch() { return thenBranch; }
public record IfNode(ExpressionNode condition, List<StatementNode> thenBranch) implements StatementNode {
}

View File

@ -1,15 +1,7 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/ImportNode.java
package org.jcnc.snow.compiler.parser.ast;
/**
* import 语句节点仅保存被导入模块名
*/
public class ImportNode implements Node {
private final String moduleName;
public ImportNode(String moduleName) {
this.moduleName = moduleName;
}
public String getModuleName() { return moduleName; }
public record ImportNode(String moduleName) implements Node {
}

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/LoopNode.java
package org.jcnc.snow.compiler.parser.ast;
import java.util.List;
@ -6,24 +5,6 @@ import java.util.List;
/**
* loop 语句节点包含初始化语句条件表达式更新语句和循环体
*/
public class LoopNode implements StatementNode {
private final StatementNode initializer;
private final ExpressionNode condition;
private final StatementNode update;
private final List<StatementNode> body;
public LoopNode(StatementNode initializer,
ExpressionNode condition,
StatementNode update,
List<StatementNode> body) {
this.initializer = initializer;
this.condition = condition;
this.update = update;
this.body = body;
}
public StatementNode getInitializer() { return initializer; }
public ExpressionNode getCondition() { return condition; }
public StatementNode getUpdate() { return update; }
public List<StatementNode> getBody() { return body; }
public record LoopNode(StatementNode initializer, ExpressionNode condition, StatementNode update,
List<StatementNode> body) implements StatementNode {
}

View File

@ -1,20 +1,9 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/MemberExpressionNode.java
package org.jcnc.snow.compiler.parser.ast;
/**
* 成员访问表达式节点 obj.prop
*/
public class MemberExpressionNode implements ExpressionNode {
private final ExpressionNode object;
private final String member;
public MemberExpressionNode(ExpressionNode object, String member) {
this.object = object;
this.member = member;
}
public ExpressionNode getObject() { return object; }
public String getMember() { return member; }
public record MemberExpressionNode(ExpressionNode object, String member) implements ExpressionNode {
@Override
public String toString() {
return object + "." + member;

View File

@ -37,11 +37,11 @@ public class ModuleNode implements Node {
public String toString() {
StringJoiner importJoiner = new StringJoiner(", ");
for (ImportNode imp : imports) {
importJoiner.add(imp.getModuleName());
importJoiner.add(imp.moduleName());
}
StringJoiner funcJoiner = new StringJoiner(", ");
for (FunctionNode fn : functions) {
funcJoiner.add(fn.getName());
funcJoiner.add(fn.name());
}
return "Module(name=" + name
+ ", imports=[" + importJoiner.toString() + "]"

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/Node.java
package org.jcnc.snow.compiler.parser.ast;
/**

View File

@ -1,17 +1,9 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/NumberLiteralNode.java
package org.jcnc.snow.compiler.parser.ast;
/**
* 数字字面量表达式节点
*/
public class NumberLiteralNode implements ExpressionNode {
private final String value;
public NumberLiteralNode(String value) {
this.value = value;
}
public String getValue() { return value; }
public record NumberLiteralNode(String value) implements ExpressionNode {
@Override
public String toString() {

View File

@ -1,25 +1,9 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/ParameterNode.java
package org.jcnc.snow.compiler.parser.ast;
/**
* 函数参数节点包含参数名和类型
*/
public class ParameterNode implements Node {
private final String name;
private final String type;
public ParameterNode(String name, String type) {
this.name = name;
this.type = type;
}
public String getName() {
return name;
}
public String getType() {
return type;
}
public record ParameterNode(String name, String type) implements Node {
/**
* 返回参数的字符串表示例如 "num1:int"便于列表打印

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/ReturnNode.java
package org.jcnc.snow.compiler.parser.ast;
import java.util.Optional;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/StatementNode.java
package org.jcnc.snow.compiler.parser.ast;
/**

View File

@ -1,20 +1,11 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/ast/StringLiteralNode.java
package org.jcnc.snow.compiler.parser.ast;
/**
* 字符串字面量表达式节点 "hello"
*
* @param value 不包含引号的字符串内容
*/
public class StringLiteralNode implements ExpressionNode {
/** 不包含引号的字符串内容 */
private final String value;
public StringLiteralNode(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public record StringLiteralNode(String value) implements ExpressionNode {
/**
* 打印时在两端加上引号

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/context/ParseException.java
package org.jcnc.snow.compiler.parser.context;
/**

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/context/ParserContext.java
package org.jcnc.snow.compiler.parser.context;
import org.jcnc.snow.compiler.lexer.token.Token;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/context/TokenStream.java
package org.jcnc.snow.compiler.parser.context;
import org.jcnc.snow.compiler.lexer.token.Token;
@ -73,6 +72,6 @@ public class TokenStream {
}
public boolean isAtEnd() {
return peek().getType() == TokenType.EOF;
return peek().getType() != TokenType.EOF;
}
}

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/expression/BinaryOperatorParselet.java
package org.jcnc.snow.compiler.parser.expression;
import org.jcnc.snow.compiler.parser.ast.BinaryExpressionNode;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/expression/CallParselet.java
package org.jcnc.snow.compiler.parser.expression;
import org.jcnc.snow.compiler.parser.ast.CallExpressionNode;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/expression/ExpressionParser.java
package org.jcnc.snow.compiler.parser.expression;
import org.jcnc.snow.compiler.parser.ast.ExpressionNode;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/expression/GroupingParselet.java
package org.jcnc.snow.compiler.parser.expression;
import org.jcnc.snow.compiler.lexer.token.Token;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/expression/IdentifierParselet.java
package org.jcnc.snow.compiler.parser.expression;
import org.jcnc.snow.compiler.lexer.token.Token;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/expression/MemberParselet.java
package org.jcnc.snow.compiler.parser.expression;
import org.jcnc.snow.compiler.lexer.token.TokenType;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/expression/NumberLiteralParselet.java
package org.jcnc.snow.compiler.parser.expression;
import org.jcnc.snow.compiler.lexer.token.Token;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/expression/PrattExpressionParser.java
package org.jcnc.snow.compiler.parser.expression;
import org.jcnc.snow.compiler.lexer.token.Token;
@ -51,7 +50,7 @@ public class PrattExpressionParser implements ExpressionParser {
}
ExpressionNode left = prefix.parse(ctx, token);
while (!ctx.getTokens().isAtEnd() &&
while (ctx.getTokens().isAtEnd() &&
prec.ordinal() < nextPrecedence(ctx)) {
String lex = ctx.getTokens().peek().getLexeme();
InfixParselet infix = infixes.get(lex);

View File

@ -1,4 +1,4 @@
package org.jcnc.snow.compiler.parser.expression;// File: src/main/java/org/jcnc/snow/compiler/parser/expression/Precedence.java
package org.jcnc.snow.compiler.parser.expression;
/**
* 运算符优先级枚举用于 Pratt 算法比较

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/expression/PrefixParselet.java
package org.jcnc.snow.compiler.parser.expression;
import org.jcnc.snow.compiler.parser.ast.ExpressionNode;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/expression/StringLiteralParselet.java
package org.jcnc.snow.compiler.parser.expression;
import org.jcnc.snow.compiler.lexer.token.Token;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/factory/StatementParserFactory.java
package org.jcnc.snow.compiler.parser.factory;
import org.jcnc.snow.compiler.parser.statement.*;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/factory/TopLevelParserFactory.java
package org.jcnc.snow.compiler.parser.factory;
import org.jcnc.snow.compiler.parser.TopLevelParser;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/function/FunctionParser.java
package org.jcnc.snow.compiler.parser.function;
import org.jcnc.snow.compiler.lexer.token.TokenType;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/module/ImportParser.java
package org.jcnc.snow.compiler.parser.module;
import org.jcnc.snow.compiler.lexer.token.TokenType;
@ -21,17 +20,13 @@ public class ImportParser {
ctx.getTokens().expect(":");
List<ImportNode> imports = new ArrayList<>();
// 读取第一个模块名
String name = ctx.getTokens()
.expectType(TokenType.IDENTIFIER)
.getLexeme();
imports.add(new ImportNode(name));
// 继续读取逗号分隔的模块名
while (ctx.getTokens().match(",")) {
do {
String mod = ctx.getTokens()
.expectType(TokenType.IDENTIFIER)
.getLexeme();
imports.add(new ImportNode(mod));
}
} while (ctx.getTokens().match(","));
// 消费行尾
ctx.getTokens().expectType(TokenType.NEWLINE);
return imports;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/module/ModuleParser.java
package org.jcnc.snow.compiler.parser.module;
import org.jcnc.snow.compiler.lexer.token.TokenType;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/statement/DeclarationStatementParser.java
package org.jcnc.snow.compiler.parser.statement;
import org.jcnc.snow.compiler.lexer.token.TokenType;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/statement/ExpressionStatementParser.java
package org.jcnc.snow.compiler.parser.statement;
import org.jcnc.snow.compiler.lexer.token.TokenType;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/statement/IfStatementParser.java
package org.jcnc.snow.compiler.parser.statement;
import org.jcnc.snow.compiler.lexer.token.TokenType;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/statement/LoopStatementParser.java
package org.jcnc.snow.compiler.parser.statement;
import org.jcnc.snow.compiler.lexer.token.TokenType;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/statement/ReturnStatementParser.java
package org.jcnc.snow.compiler.parser.statement;
import org.jcnc.snow.compiler.lexer.token.TokenType;

View File

@ -1,4 +1,3 @@
// File: src/main/java/org/jcnc/snow/compiler/parser/statement/StatementParser.java
package org.jcnc.snow.compiler.parser.statement;
import org.jcnc.snow.compiler.parser.context.ParserContext;