/// <summary> /// ClassStmt /// CLASS ID LBRACES DeclarationStmt* RBRACES /// </summary> /// <returns></returns> private ClassStmt ParseClassStmt() { Consume(TokenType.CLASS); ClassStmt ret = new ClassStmt(Consume(TokenType.ID).Literal); FuncStmt fs = null; FuncStmt fcur = null; VarStmt vs = null; VarStmt vcur = null; Consume(TokenType.LBRACES); while (!Check(TokenType.RBRACES)) { DeclarationStmt stmt = ParseDeclOrDefStmt(); if (stmt is FuncStmt) { AppendASTLinkedList(ref fs, ref fcur, (FuncStmt)stmt); } else { AppendASTLinkedList(ref vs, ref vcur, (VarStmt)stmt); } } Consume(TokenType.RBRACES); ret.Methods = fs; ret.Fields = vs; return(ret); }
/// <summary> /// Params /// TypeExpr Id (COMMA Params)? /// </summary> /// <returns></returns> private VarStmt ParseParams() { TypeExpr type = ParseTypeExpr(); IdExpr id = ParseId(); VarStmt vars = new VarStmt(AccessFlag.DefaultFlag, type, id.Id, null); if (Check(TokenType.COMMA)) { Consume(TokenType.COMMA); vars.SiblingAST = ParseParams(); } return(vars); }
/// <summary> /// 这里用了LookAhead /// 此外不允许不带定义的声明 /// DeclarationStmt /// ACCESS_FLAG* TypeExpr FuncDeclarator BlockStmt /// ACCESS_FLAG* TypeExpr VarDeclarator SEMICOLON /// </summary> /// <returns></returns> private DeclarationStmt ParseDeclOrDefStmt() { AccessFlag flag = ParserAccessFlag(); TypeExpr type = ParseTypeExpr(); if (Check(TokenType.LPAREN) || CheckAt(1, TokenType.LPAREN)) { FuncStmt ret = ParseFuncDeclarator(type, flag); ret.Body = ParseBlockStmt(); return(ret); } else { VarStmt ret = ParseVarDeclarator(type, flag); Consume(TokenType.SEMICOLON); return(ret); } }
/// <summary> /// VarDeclarator /// Id (ASSIGN Expr)? (COMMA VarDeclarator)? /// </summary> /// <param name="flag"></param> /// <param name="type"></param> /// <returns></returns> private VarStmt ParseVarDeclarator(TypeExpr type, AccessFlag flag) { Expr declarator = ParseExpr(true); VarStmt vars; if (declarator is IdExpr idExpr) { vars = new VarStmt(flag, type, idExpr.Id, null); } else { vars = new VarStmt(flag, type, ((IdExpr)declarator.Expr1).Id, declarator.Expr2); } if (Check(TokenType.COMMA)) { Consume(TokenType.COMMA); vars.SiblingAST = ParseVarDeclarator(type, flag); } return(vars); }