diff --git a/src/main/java/org/jcnc/snow/compiler/parser/statement/ExpressionStatementParser.java b/src/main/java/org/jcnc/snow/compiler/parser/statement/ExpressionStatementParser.java index 955baa7..766f53d 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/statement/ExpressionStatementParser.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/statement/ExpressionStatementParser.java @@ -14,17 +14,17 @@ import org.jcnc.snow.compiler.parser.expression.PrattExpressionParser; /** * {@code ExpressionStatementParser} 用于解析通用表达式语句(赋值或普通表达式)。 *
- * 支持以下两种语法结构: + * 支持以下两种语法结构: *
{@code
* x = 1 + 2 // 赋值语句
* doSomething() // 一般表达式语句
+ * this.name = n // 将 this.name 赋值语法糖为对 name 的赋值
* }
- *
*/
public class ExpressionStatementParser implements StatementParser {
@@ -33,49 +33,81 @@ public class ExpressionStatementParser implements StatementParser {
*
* @param ctx 当前解析上下文,提供词法流与环境信息
* @return {@link AssignmentNode} 或 {@link ExpressionStatementNode} 语法节点
- * @throws UnexpectedToken 若遇到非法起始(关键字、空行等)
+ * @throws UnexpectedToken 若遇到非法起始(关键字 'end' 等)
*/
@Override
public StatementNode parse(ParserContext ctx) {
TokenStream ts = ctx.getTokens();
- if (ts.peek().getType() == TokenType.NEWLINE || ts.peek().getType() == TokenType.KEYWORD) {
+ // ----------- 起始 token 合法性检查(放宽以支持 this 开头)-----------
+ if (ts.peek().getType() == TokenType.NEWLINE) {
+ // 空行不应进入表达式解析,直接抛出异常
throw new UnexpectedToken(
- "无法解析以关键字开头的表达式: " + ts.peek().getLexeme(),
+ "无法解析以空行开头的表达式",
ts.peek().getLine(),
ts.peek().getCol()
);
}
+ if (ts.peek().getType() == TokenType.KEYWORD) {
+ String kw = ts.peek().getLexeme();
+ // 仅允许 this 作为表达式起始;其它关键字(如 end/if/else 等)仍禁止
+ if (!"this".equals(kw)) {
+ throw new UnexpectedToken(
+ "无法解析以关键字开头的表达式: " + kw,
+ ts.peek().getLine(),
+ ts.peek().getCol()
+ );
+ }
+ }
int line = ts.peek().getLine();
int column = ts.peek().getCol();
String file = ctx.getSourceName();
- // 简单形式: IDENTIFIER = expr
+ // ------------- 简单形式: IDENTIFIER = expr -------------
+ // 快速路径:如 "a = ...",直接识别为赋值语句,无需完整表达式树回退
if (ts.peek().getType() == TokenType.IDENTIFIER && "=".equals(ts.peek(1).getLexeme())) {
- String varName = ts.next().getLexeme();
- ts.expect("=");
- ExpressionNode value = new PrattExpressionParser().parse(ctx);
+ String varName = ts.next().getLexeme(); // 消费 IDENTIFIER
+ ts.expect("="); // 消费 '='
+ ExpressionNode value = new PrattExpressionParser().parse(ctx); // 解析右侧表达式
ts.expectType(TokenType.NEWLINE);
+ // 返回简单变量赋值节点
return new AssignmentNode(varName, value, new NodeContext(line, column, file));
}
- // 尝试解析更通用的左值形式(支持下标):