using System.Globalization; using Canon.Core.Abstractions; using Canon.Core.CodeGenerators; using Canon.Core.Enums; using Canon.Core.GrammarParser; using Canon.Core.LexicalParser; using Canon.Core.SyntaxNodes; using BasicType = Canon.Core.Enums.BasicType; using Expression = Canon.Core.SyntaxNodes.Expression; namespace Canon.Core.SemanticParser; public class CodeGeneratorVisitor(ICompilerLogger? logger = null) : TypeCheckVisitor(logger) { public CCodeBuilder Builder { get; } = new(); public override void PreVisit(ProgramHead programHead) { base.PreVisit(programHead); Builder.AddLine("#include "); Builder.AddLine("#include "); } public override void PreVisit(ProgramBody programBody) { base.PreVisit(programBody); programBody.CompoundStatement.IsMain = true; } public override void PostVisit(ConstDeclaration constDeclaration) { base.PreVisit(constDeclaration); (IdentifierSemanticToken token, ConstValue constValue) = constDeclaration.ConstValue; if (SymbolTable.TryGetSymbol(token.IdentifierName, out Symbol? symbol)) { Builder.AddLine( $"const {GenerateBasicTypeString(symbol.SymbolType)} {token.IdentifierName} = {constValue.ValueString};"); } } public override void PostVisit(ConstValue constValue) { base.PostVisit(constValue); constValue.OnNumberGenerator += (_, e) => { string numberValue = e.IsNegative ? "-" : "+"; if (constValue.ConstType == PascalBasicType.Integer) { numberValue += e.Token.ParseAsInteger().ToString(); } else if (constValue.ConstType == PascalBasicType.Real) { numberValue += e.Token.ParseAsReal().ToString(CultureInfo.CurrentCulture); } constValue.ValueString = numberValue; }; constValue.OnCharacterGenerator += (_, e) => { constValue.ValueString = $"'{e.Token.LiteralValue}'"; }; } public override void PreVisit(VarDeclaration varDeclaration) { base.PreVisit(varDeclaration); varDeclaration.IdentifierList.IsVariableDefinition = true; } public override void PostVisit(VarDeclaration varDeclaration) { base.PostVisit(varDeclaration); if (varDeclaration.IdentifierList.DefinitionType is PascalBasicType) { Builder.AddLine($"{GenerateBasicTypeString(varDeclaration.IdentifierList.DefinitionType)} " + $"{varDeclaration.Token.IdentifierName};"); } if (varDeclaration.IdentifierList.DefinitionType is PascalArrayType) { (string basicValue, string periodValue) = GenerateArrayTypeString( varDeclaration.IdentifierList.DefinitionType); Builder.AddLine($"{basicValue} {varDeclaration.Token.IdentifierName}{periodValue};"); } } public override void PreVisit(IdentifierList identifierList) { base.PreVisit(identifierList); identifierList.OnIdentifierGenerator += (_, e) => { if (identifierList.IsVariableDefinition) { e.IdentifierList.IsVariableDefinition = true; } }; } public override void PostVisit(IdentifierList identifierList) { base.PostVisit(identifierList); identifierList.OnIdentifierGenerator += (_, e) => { if (!identifierList.IsVariableDefinition) { return; } if (identifierList.DefinitionType is PascalArrayType) { (string basicTypeString, string periodString) = GenerateArrayTypeString(identifierList.DefinitionType); Builder.AddLine($"{basicTypeString} {e.IdentifierToken.IdentifierName}{periodString};"); } if (identifierList.DefinitionType is PascalBasicType) { Builder.AddLine($"{GenerateBasicTypeString(identifierList.DefinitionType)} " + $"{e.IdentifierToken.IdentifierName};"); } }; } public override void PreVisit(CompoundStatement compoundStatement) { if (compoundStatement.IsMain) { Builder.AddLine("int main()"); } Builder.BeginScope(); } public override void PostVisit(CompoundStatement compoundStatement) { if (compoundStatement.IsMain) { Builder.AddLine("return 0;"); } Builder.EndScope(); } public override void PreVisit(Factor factor) { base.PreVisit(factor); factor.OnParethnesisGenerator += (_, e) => { e.Expression.IsCondition = factor.IsCondition; }; factor.OnNotGenerator += (_, e) => { e.Factor.IsCondition = factor.IsCondition; }; factor.OnUminusGenerator += (_, e) => { e.Factor.IsCondition = factor.IsCondition; }; factor.OnPlusGenerator += (_, e) => { e.Factor.IsCondition = factor.IsCondition; }; } public override void PostVisit(Factor factor) { base.PostVisit(factor); factor.OnNumberGenerator += (_, e) => { string temporaryName = GenerateTemporaryVariable(); switch (e.Token.NumberType) { case NumberType.Integer: Builder.AddLine($"int {temporaryName} = {e.Token.ParseAsInteger()};"); break; case NumberType.Real: Builder.AddLine($"double {temporaryName} = {e.Token.ParseAsReal()};"); break; } factor.VariableName = temporaryName; }; factor.OnBooleanGenerator += (_, e) => { string temporaryName = GenerateTemporaryVariable(); string value = e.Value ? "true" : "false"; Builder.AddLine($"bool {temporaryName} = {value};"); factor.VariableName = temporaryName; }; factor.OnVariableGenerator += (_, e) => { if (SymbolTable.TryGetSymbol(e.Variable.VariableName, out Symbol? symbol)) { // 处理不带括号调用无参函数的问题 if (symbol.SymbolType is PascalFunctionType { Parameters.Count: 0 } functionType) { string temporaryName = GenerateTemporaryVariable(); Builder.AddLine($"{GenerateBasicTypeString(functionType.ReturnType)} {temporaryName} = " + $"{symbol.SymbolName}_pascal_procedure();"); factor.VariableName = temporaryName; return; } } factor.VariableName = e.Variable.VariableName; }; factor.OnParethnesisGenerator += (_, e) => { factor.VariableName = e.Expression.VariableName; }; factor.OnNotGenerator += (_, e) => { string temporaryName = GenerateTemporaryVariable(); Builder.AddLine( $"{GenerateBasicTypeString(factor.VariableType)} {temporaryName} = ~{e.Factor.VariableName};"); factor.VariableName = temporaryName; }; factor.OnPlusGenerator += (_, e) => { factor.VariableName = e.Factor.VariableName; }; factor.OnUminusGenerator += (_, e) => { string temporaryName = GenerateTemporaryVariable(); Builder.AddLine( $"{GenerateBasicTypeString(factor.VariableType)} {temporaryName} = -{e.Factor.VariableName};"); factor.VariableName = temporaryName; }; factor.OnProcedureCallGenerator += (_, e) => { string temporaryName = GenerateTemporaryVariable(); Builder.AddLine($"{GenerateBasicTypeString(factor.VariableType)} {temporaryName}= " + $"{GenerateProcedureCall(e.ProcedureName.IdentifierName, e.Parameters)};"); factor.VariableName = temporaryName; }; } public override void PostVisit(Variable variable) { base.PostVisit(variable); if (!SymbolTable.TryGetSymbol(variable.Identifier.IdentifierName, out Symbol? symbol)) { return; } PascalType type = symbol.SymbolType; if (type is PascalArrayType) { string indexValue = string.Empty; foreach (Expression expression in variable.VarPart.Expressions) { PascalArrayType arrayType = type.Convert(); string temporaryName = GenerateTemporaryVariable(); Builder.AddLine($"int {temporaryName} = {expression.VariableName} - {arrayType.Begin};"); indexValue += $"[{temporaryName}]"; type = arrayType.ElementType; } variable.VariableName = variable.Identifier.IdentifierName + indexValue; return; } // 虽然这里这样可能会生成来类似于 &*x 的代码 // 但是可以正常运行 variable.VariableName = symbol.SymbolType.IsReference ? $"*{variable.Identifier.IdentifierName}" : variable.Identifier.IdentifierName; } private record CircuitLabel(string Circuit, string End); private readonly Stack _andCircuitLabels = []; private readonly Stack _orCircuitLabels = []; public override void PreVisit(Term term) { base.PreVisit(term); term.OnMultiplyGenerator += (_, e) => { e.Left.IsCondition = term.IsCondition; e.Right.IsCondition = term.IsCondition; if (e.Operator.OperatorToken == new Terminator(KeywordType.And)) { _andCircuitLabels.Push(new CircuitLabel($"and_circult_{_labelCount}", $"and_end_{_labelCount}")); _labelCount += 1; } }; term.OnFactorGenerator += (_, e) => { e.Factor.IsCondition = term.IsCondition; }; } private string? _termVariableName; public override void PostVisit(Term term) { base.PostVisit(term); term.OnFactorGenerator += (_, e) => { term.VariableName = e.Factor.VariableName; _termVariableName = term.VariableName; }; term.OnMultiplyGenerator += (_, e) => { string temporaryName = GenerateTemporaryVariable(); if (e.Operator.OperatorToken == new Terminator(KeywordType.And)) { // 处理and的短路代码 Builder.AddLine($""" bool {temporaryName} = {e.Left.VariableName} && {e.Right.VariableName}; goto {_andCircuitLabels.Peek().End}; {_andCircuitLabels.Peek().Circuit}:; {temporaryName} = false; {_andCircuitLabels.Peek().End}:; """); _andCircuitLabels.Pop(); } else { Builder.AddLine( $"{GenerateBasicTypeString(term.VariableType)} {temporaryName} = " + $"{e.Left.VariableName} {GenerateMultipleOperator(e.Operator)} {e.Right.VariableName};"); } term.VariableName = temporaryName; _termVariableName = temporaryName; }; } public override void PreVisit(SimpleExpression simpleExpression) { base.PreVisit(simpleExpression); simpleExpression.OnAddGenerator += (_, e) => { e.Left.IsCondition = simpleExpression.IsCondition; e.Right.IsCondition = simpleExpression.IsCondition; if (e.Operator.OperatorToken == new Terminator(KeywordType.Or)) { _orCircuitLabels.Push(new CircuitLabel($"or_circuit_{_labelCount}", $"or_end_circuit_{_labelCount}")); _labelCount += 1; } }; simpleExpression.OnTermGenerator += (_, e) => { e.Term.IsCondition = simpleExpression.IsCondition; }; } private string? _simpleExpressionVairableName; public override void PostVisit(SimpleExpression simpleExpression) { base.PostVisit(simpleExpression); simpleExpression.OnTermGenerator += (_, e) => { simpleExpression.VariableName = e.Term.VariableName; _simpleExpressionVairableName = simpleExpression.VariableName; }; simpleExpression.OnAddGenerator += (_, e) => { string temporaryName = GenerateTemporaryVariable(); if (e.Operator.OperatorToken == new Terminator(KeywordType.Or)) { // or的短路代码 Builder.AddLine($""" bool {temporaryName}; {temporaryName} = {e.Left.VariableName} || {e.Right.VariableName}; goto {_orCircuitLabels.Peek().End}; {_orCircuitLabels.Peek().Circuit}:; {temporaryName} = true; {_orCircuitLabels.Peek().End}:; """); _orCircuitLabels.Pop(); } else { Builder.AddLine( $"{GenerateBasicTypeString(simpleExpression.VariableType)} {temporaryName} = " + $"{e.Left.VariableName} {GenerateAddOperator(e.Operator)} {e.Right.VariableName};"); } simpleExpression.VariableName = temporaryName; _simpleExpressionVairableName = temporaryName; }; } public override void PreVisit(Expression expression) { base.PreVisit(expression); expression.OnSimpleExpressionGenerator += (_, e) => { e.SimpleExpression.IsCondition = expression.IsCondition; }; expression.OnRelationGenerator += (_, e) => { e.Left.IsCondition = expression.IsCondition; e.Right.IsCondition = expression.IsCondition; }; if (expression.IsWhileCondition) { GenerateWhileLabel(); Builder.AddLine($""" {_whileBeginLabels.Peek()}:; """); } } public override void PostVisit(Expression expression) { base.PostVisit(expression); expression.OnSimpleExpressionGenerator += (_, e) => { expression.VariableName = e.SimpleExpression.VariableName; HandleExpression(expression); }; expression.OnRelationGenerator += (_, e) => { string temporaryName = GenerateTemporaryVariable(); Builder.AddLine($"{GenerateBasicTypeString(expression.VariableType)} {temporaryName} = " + $"{e.Left.VariableName} {GenerateRelationOperator(e.Operator)} {e.Right.VariableName};"); expression.VariableName = temporaryName; HandleExpression(expression); }; } private void HandleExpression(Expression expression) { if (expression.IsIfCondition) { _ifConditionNames.Push(expression.VariableName); } if (expression.IsForConditionBegin) { _forBeginConditions.Push(expression.VariableName); } if (expression.IsForConditionEnd) { _forEndConditions.Push(expression.VariableName); } if (expression.IsWhileCondition) { _whileConditionNames.Push(expression.VariableName); } } /// /// 存储IF语句中条件变量的名称 /// private readonly Stack _ifConditionNames = new(); /// /// IF语句中成功分支的标签 /// private readonly Stack _ifTrueLabels = new(); /// /// IF语句中失败分支的标签 /// private readonly Stack _ifFalseLabels = new(); /// /// IF语句中结束的标签 /// private readonly Stack _ifEndLabels = new(); /// /// FOR语句中的循环变量名称 /// private readonly Stack _forVariables = new(); /// /// FOR语句中的循环变量的初始值 /// private readonly Stack _forBeginConditions = new(); /// /// FOR语句中循环变量的判断值 /// private readonly Stack _forEndConditions = new(); /// /// FOR语句开始的标签 /// private readonly Stack _forLabels = new(); /// /// FOR语句条件判断部分的标签 /// private readonly Stack _forConditionLabels = new(); /// /// FOR语句结束的标签 /// private readonly Stack _forEndLabels = new(); /// /// WHILE语句条件变量的标签 /// private readonly Stack _whileConditionNames = new(); /// /// WHILE语句开始的标签 /// private readonly Stack _whileBeginLabels = new(); /// /// WHILE语句结束的标签 /// private readonly Stack _whileEndLabels = new(); public override void PreVisit(Statement statement) { base.PreVisit(statement); statement.OnIfGenerator += (_, e) => { e.Condition.IsIfCondition = true; e.Condition.IsCondition = true; }; statement.OnForGenerator += (_, e) => { e.Begin.IsForConditionBegin = true; e.End.IsForConditionEnd = true; e.Do.IsForNode = true; _forVariables.Push(e.Iterator.IdentifierName); }; statement.OnWhileGenerator += (_, e) => { e.Do.IsWhileNode = true; e.Condition.IsWhileCondition = true; }; } public override void PostVisit(Statement statement) { base.PostVisit(statement); statement.OnAssignGenerator += (_, e) => { Builder.AddLine($"{e.Variable.VariableName} = {e.Expression.VariableName};"); }; statement.OnForGenerator += (_, _) => { Builder.AddLine($""" {_forVariables.Peek()} = {_forVariables.Peek()} + 1; goto {_forConditionLabels.Peek()}; {_forEndLabels.Peek()}:; """); _forLabels.Pop(); _forConditionLabels.Pop(); _forEndLabels.Pop(); _forVariables.Pop(); _forBeginConditions.Pop(); _forEndConditions.Pop(); }; statement.OnWhileGenerator += (_, _) => { Builder.AddLine($""" goto {_whileBeginLabels.Peek()}; {_whileEndLabels.Peek()}:; """); _whileBeginLabels.Pop(); _whileEndLabels.Pop(); _whileConditionNames.Pop(); }; } public override void PreVisit(ElsePart elsePart) { base.PreVisit(elsePart); // 这是成功分支跳过Else的语句 Builder.AddLine($"goto {_ifEndLabels.Peek()};"); Builder.AddLine($"{_ifFalseLabels.Peek()}:;"); } public override void PostVisit(ElsePart elsePart) { base.PostVisit(elsePart); Builder.AddLine($"{_ifEndLabels.Peek()}:;"); _ifConditionNames.Pop(); _ifTrueLabels.Pop(); _ifFalseLabels.Pop(); _ifEndLabels.Pop(); } public override void PostVisit(ProcedureCall procedureCall) { base.PostVisit(procedureCall); Builder.AddLine(GenerateProcedureCall(procedureCall.ProcedureId.IdentifierName, procedureCall.Parameters) + ";"); } public override void PostVisit(SubprogramHead subprogramHead) { base.PostVisit(subprogramHead); subprogramHead.OnProcedureGenerator += (_, _) => { GenerateProcedureHead(subprogramHead.SubprogramName.IdentifierName); }; subprogramHead.OnFunctionGenerator += (_, _) => { GenerateProcedureHead(subprogramHead.SubprogramName.IdentifierName); }; } private Symbol? _function; private void GenerateProcedureHead(string procedureId) { if (!SymbolTable.TryGetParent(out SymbolTable? parent)) { return; } if (!parent.TryGetSymbol(procedureId, out Symbol? symbol)) { return; } if (symbol.SymbolType is not PascalFunctionType functionType) { return; } _function = symbol; string result = $"{GenerateBasicTypeString(functionType.ReturnType)} {procedureId}_pascal_procedure("; // 控制格式 bool isStart = true; foreach (PascalParameterType parameter in functionType.Parameters) { string value = string.Empty; if (parameter.ParameterType is PascalBasicType) { value = $"{GenerateBasicTypeString(parameter.ParameterType)} {parameter.ParameterName}"; } if (parameter.ParameterType is PascalArrayType) { value = $"{GenerateArrayTypeString(parameter.ParameterType)} {parameter.ParameterName}"; } if (isStart) { result += value; } else { result += ", " + value; } isStart = false; } result += ")"; Builder.AddLine(result); } public override void PreVisit(SubprogramBody subprogramBody) { base.PreVisit(subprogramBody); Builder.BeginScope(); if (_function is null) { return; } PascalFunctionType functionType = _function.SymbolType.Convert(); if (functionType.ReturnType != PascalBasicType.Void) { Builder.AddLine($"{GenerateBasicTypeString(functionType.ReturnType)} {_function.SymbolName};"); } } public override void PostVisit(SubprogramBody subprogramBody) { base.PostVisit(subprogramBody); if (_function is null) { return; } PascalFunctionType functionType = _function.SymbolType.Convert(); if (functionType.ReturnType != PascalBasicType.Void) { Builder.AddLine($"return {_function.SymbolName};"); } Builder.EndScope(); } public override void PostVisit(TerminatedSyntaxNode terminatedSyntaxNode) { base.PostVisit(terminatedSyntaxNode); if (terminatedSyntaxNode.Token.TokenType == SemanticTokenType.Keyword) { KeywordType keywordType = terminatedSyntaxNode.Token.Convert().KeywordType; switch (keywordType) { case KeywordType.Then: GenerateIfLabel(); Builder.AddLine($""" if ({_ifConditionNames.Peek()}) goto {_ifTrueLabels.Peek()}; else goto {_ifFalseLabels.Peek()}; {_ifTrueLabels.Peek()}:; """); break; case KeywordType.To: GenerateForLabel(); Builder.AddLine($""" {_forVariables.Peek()} = {_forBeginConditions.Peek()}; {_forConditionLabels.Peek()}:; """); break; case KeywordType.Do: if (terminatedSyntaxNode.IsForNode) { Builder.AddLine($""" if ({_forVariables.Peek()} <= {_forEndConditions.Peek()}) goto {_forLabels.Peek()}; else goto {_forEndLabels.Peek()}; {_forLabels.Peek()}:; """); } if (terminatedSyntaxNode.IsWhileNode) { // GenerateWhileLabel(); Builder.AddLine($""" if (!{_whileConditionNames.Peek()}) goto {_whileEndLabels.Peek()}; """); } break; case KeywordType.And: // 加上and短路的判断代码 Builder.AddLine($""" if (!{_termVariableName}) goto {_andCircuitLabels.Peek().Circuit}; """); break; case KeywordType.Or: // 加上or短路的判断代码 Builder.AddLine($""" if ({_simpleExpressionVairableName}) goto {_orCircuitLabels.Peek().Circuit}; """); break; } } } private string GenerateProcedureCall(string procedureId, List parameters) { string isReturn = procedureId == "writeln" || procedureId == "readln" ? "\\n" : string.Empty; if (procedureId == "write" || procedureId == "writeln") { string result = $"printf(\"{GenerateFormatString(parameters, true) + isReturn}\""; foreach (Expression parameter in parameters) { result += $", {parameter.VariableName}"; } return result + ")"; } if (procedureId == "read" || procedureId == "readln") { string result = $"scanf(\"{GenerateFormatString(parameters) + isReturn}\""; foreach (Expression parameter in parameters) { result += $", &{parameter.VariableName}"; } return result + ")"; } if (!SymbolTable.TryGetSymbol(procedureId, out Symbol? symbol)) { return string.Empty; } string parameterValue = string.Empty; PascalFunctionType functionType; if (symbol.SymbolType is not PascalFunctionType innerType) { // 处理函数内部的递归调用 if (!SymbolTable.TryGetParent(out SymbolTable? parent)) { return string.Empty; } if (!parent.TryGetSymbol(procedureId, out symbol)) { return string.Empty; } if (symbol.SymbolType is PascalFunctionType outerType) { functionType = outerType; } else { return string.Empty; } } else { functionType = innerType; } foreach ((Expression parameter, PascalParameterType parameterType) in parameters.Zip(functionType.Parameters)) { if (parameterType.ParameterType.IsReference) { parameterValue += $", &{parameter.VariableName}"; } else { parameterValue += $", {parameter.VariableName}"; } } parameterValue = parameterValue == string.Empty ? parameterValue : parameterValue[1..]; return $"{procedureId}_pascal_procedure({parameterValue})"; } private static string GenerateFormatString(List expressions, bool output = false) { string value = string.Empty; foreach (Expression expression in expressions) { if (expression.VariableType == PascalBasicType.Integer) { value += "%d"; } if (expression.VariableType == PascalBasicType.Real) { // 这里需要按照输出调整 // 在输出real的前面需要添加一个空格 value += output ? "%.6lf" : "%lf"; } if (expression.VariableType == PascalBasicType.Character) { value += "%c"; } } return value; } private static string GenerateBasicTypeString(PascalType pascalType) { if (pascalType is not PascalBasicType basicType) { return string.Empty; } switch (basicType.Type) { case BasicType.Integer: return basicType.IsReference ? "int *" : "int"; case BasicType.Real: return basicType.IsReference ? "double *" : "double"; case BasicType.Character: return basicType.IsReference ? "char *" : "char"; case BasicType.Boolean: return basicType.IsReference ? "bool *" : "bool"; case BasicType.Void: return "void"; } return string.Empty; } private static (string, string) GenerateArrayTypeString(PascalType pascalType) { string periodString = string.Empty; while (pascalType is PascalArrayType arrayType) { periodString += $"[{arrayType.End - arrayType.Begin + 1}]"; pascalType = arrayType.ElementType; } return (GenerateBasicTypeString(pascalType), periodString); } private static string GenerateMultipleOperator(MultiplyOperator multiplyOperator) { if (multiplyOperator.OperatorToken.TokenType == SemanticTokenType.Operator) { OperatorType operatorType = multiplyOperator.OperatorToken.Convert().OperatorType; if (operatorType == OperatorType.Multiply) { return "*"; } else if (operatorType == OperatorType.Divide) { //实数除法,需要将操作数强转为double return "/(double)"; } } else { KeywordType keywordType = multiplyOperator.OperatorToken.Convert().KeywordType; switch (keywordType) { case KeywordType.And: return "&&"; case KeywordType.Mod: return "%"; case KeywordType.Divide: return "/"; } } return string.Empty; } private static string GenerateAddOperator(AddOperator addOperator) { SemanticToken token = addOperator.OperatorToken; if (token.TokenType == SemanticTokenType.Operator) { OperatorType operatorType = token.Convert().OperatorType; if (operatorType == OperatorType.Plus) { return "+"; } else if (operatorType == OperatorType.Minus) { return "-"; } } else { return "||"; } return string.Empty; } private static string GenerateRelationOperator(RelationOperator relationOperator) { var operatorType = relationOperator.OperatorToken.Convert().OperatorType; switch (operatorType) { case OperatorType.Equal: return "=="; case OperatorType.Greater: return ">"; case OperatorType.Less: return "<"; case OperatorType.GreaterEqual: return ">="; case OperatorType.LessEqual: return "<="; case OperatorType.NotEqual: return "!="; } return string.Empty; } private long _temporaryVariableCount; /// /// 产生一个全局唯一的临时变量名 /// private string GenerateTemporaryVariable() { string name = $"__temp_{_temporaryVariableCount}"; _temporaryVariableCount += 1; return name; } private long _labelCount; /// /// 产生一对IF语句中的标签 /// private void GenerateIfLabel() { _ifTrueLabels.Push($"if_true_{_labelCount}"); _ifFalseLabels.Push($"if_false_{_labelCount}"); _ifEndLabels.Push($"_if_end_{_labelCount}"); _labelCount += 1; } /// /// 产生FOR语句中的标签 /// private void GenerateForLabel() { _forLabels.Push($"for_{_labelCount}"); _forConditionLabels.Push($"for_condition_{_labelCount}"); _forEndLabels.Push($"for_end_{_labelCount}"); _labelCount += 1; } /// /// 产生WHILE语句中的标签 /// private void GenerateWhileLabel() { _whileBeginLabels.Push($"while_{_labelCount}"); _whileConditionNames.Push($"while_condition_{_labelCount}"); _whileEndLabels.Push($"while_end_{_labelCount}"); _labelCount += 1; } }