diff --git a/Canon.Core/SemanticParser/CodeGeneratorVisitor.cs b/Canon.Core/SemanticParser/CodeGeneratorVisitor.cs index 3e6094d..a7c8dd9 100644 --- a/Canon.Core/SemanticParser/CodeGeneratorVisitor.cs +++ b/Canon.Core/SemanticParser/CodeGeneratorVisitor.cs @@ -146,6 +146,19 @@ public class CodeGeneratorVisitor : TypeCheckVisitor 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); @@ -256,7 +269,23 @@ public class CodeGeneratorVisitor : TypeCheckVisitor return; } - variable.VariableName = variable.Identifier.IdentifierName; + // 虽然这里这样可能会生成来类似于 &*x 的代码 + // 但是可以正常运行 + variable.VariableName = + symbol.Reference ? $"*{variable.Identifier.IdentifierName}" : variable.Identifier.IdentifierName; + } + + public override void PreVisit(Term term) + { + base.PreVisit(term); + + term.OnMultiplyGenerator += (_, e) => + { + e.Left.IsCondition = term.IsCondition; + e.Right.IsCondition = term.IsCondition; + }; + + term.OnFactorGenerator += (_, e) => { e.Factor.IsCondition = term.IsCondition; }; } public override void PostVisit(Term term) @@ -276,6 +305,19 @@ public class CodeGeneratorVisitor : TypeCheckVisitor }; } + public override void PreVisit(SimpleExpression simpleExpression) + { + base.PreVisit(simpleExpression); + + simpleExpression.OnAddGenerator += (_, e) => + { + e.Left.IsCondition = simpleExpression.IsCondition; + e.Right.IsCondition = simpleExpression.IsCondition; + }; + + simpleExpression.OnTermGenerator += (_, e) => { e.Term.IsCondition = simpleExpression.IsCondition; }; + } + public override void PostVisit(SimpleExpression simpleExpression) { base.PostVisit(simpleExpression); @@ -298,6 +340,16 @@ public class CodeGeneratorVisitor : TypeCheckVisitor { 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(); @@ -306,6 +358,7 @@ public class CodeGeneratorVisitor : TypeCheckVisitor """); } } + public override void PostVisit(Expression expression) { base.PostVisit(expression); @@ -422,7 +475,11 @@ public class CodeGeneratorVisitor : TypeCheckVisitor { base.PreVisit(statement); - statement.OnIfGenerator += (_, e) => { e.Condition.IsIfCondition = true; }; + statement.OnIfGenerator += (_, e) => + { + e.Condition.IsIfCondition = true; + e.Condition.IsCondition = true; + }; statement.OnForGenerator += (_, e) => { @@ -445,16 +502,6 @@ public class CodeGeneratorVisitor : TypeCheckVisitor statement.OnAssignGenerator += (_, e) => { - if (!SymbolTable.TryGetSymbol(e.Variable.Identifier.IdentifierName, out Symbol? symbol)) - { - return; - } - - if (symbol.Reference) - { - e.Variable.VariableName = "*" + e.Variable.VariableName; - } - Builder.AddLine($"{e.Variable.VariableName} = {e.Expression.VariableName};"); }; @@ -686,7 +733,7 @@ public class CodeGeneratorVisitor : TypeCheckVisitor if (procedureId == "write" || procedureId == "writeln") { - string result = $"printf(\"{GenerateFormatString(parameters) + isReturn}\""; + string result = $"printf(\"{GenerateFormatString(parameters, true) + isReturn}\""; foreach (Expression parameter in parameters) { @@ -748,7 +795,22 @@ public class CodeGeneratorVisitor : TypeCheckVisitor { if (parameterType.IsVar) { - parameterValue += $", &{parameter.VariableName}"; + // 这里需要判断parameter是否也为引用类型 + if (SymbolTable.TryGetSymbol(parameter.VariableName, out Symbol? parameterSymboe)) + { + if (parameterSymboe.Reference) + { + parameterValue += $", {parameter.VariableName}"; + } + else + { + parameterValue += $", &{parameter.VariableName}"; + } + } + else + { + parameterValue += $", &{parameter.VariableName}"; + } } else { @@ -768,22 +830,23 @@ public class CodeGeneratorVisitor : TypeCheckVisitor { if (expression.VariableType == PascalBasicType.Integer) { - value += "%d "; + value += "%d"; } if (expression.VariableType == PascalBasicType.Real) { // 这里需要按照输出调整 - value += output ? "%.6lf " : "%lf "; + // 在输出real的前面需要添加一个空格 + value += output ? "%.6lf" : "%lf"; } if (expression.VariableType == PascalBasicType.Character) { - value += "%c "; + value += "%c"; } } - return value.Trim(); + return value; } private static string GenerateBasicTypeString(PascalType pascalType) diff --git a/Canon.Core/SyntaxNodes/Expression.cs b/Canon.Core/SyntaxNodes/Expression.cs index 36ec1ca..8f5d07d 100644 --- a/Canon.Core/SyntaxNodes/Expression.cs +++ b/Canon.Core/SyntaxNodes/Expression.cs @@ -48,6 +48,11 @@ public class Expression : NonTerminatedSyntaxNode /// public bool IsIfCondition { get; set; } + /// + /// 是否为条件判断语句 + /// + public bool IsCondition { get; set; } + /// /// 是否为WHILE语句中的条件语句 /// diff --git a/Canon.Core/SyntaxNodes/Factor.cs b/Canon.Core/SyntaxNodes/Factor.cs index 03ed69d..74c3e90 100644 --- a/Canon.Core/SyntaxNodes/Factor.cs +++ b/Canon.Core/SyntaxNodes/Factor.cs @@ -50,6 +50,11 @@ public class Factor : NonTerminatedSyntaxNode { public override NonTerminatorType Type => NonTerminatorType.Factor; + /// + /// 是否为条件判断语句 + /// + public bool IsCondition { get; set; } + public override void PreVisit(SyntaxNodeVisitor visitor) { visitor.PreVisit(this); @@ -158,10 +163,11 @@ public class Factor : NonTerminatedSyntaxNode else { // factor -> id ( ) - OnProcedureCallGenerator?.Invoke(this, new ProcedureCallGeneratorEventArgs - { - ProcedureName = terminatedSyntaxNode.Token.Convert() - }); + OnProcedureCallGenerator?.Invoke(this, + new ProcedureCallGeneratorEventArgs + { + ProcedureName = terminatedSyntaxNode.Token.Convert() + }); } } else if (Children.Count == 4) @@ -177,7 +183,6 @@ public class Factor : NonTerminatedSyntaxNode } else { - SemanticToken token = Children[0].Convert().Token; Factor factor = Children[1].Convert(); diff --git a/Canon.Core/SyntaxNodes/SimpleExpression.cs b/Canon.Core/SyntaxNodes/SimpleExpression.cs index 65a27c1..ab3e5bb 100644 --- a/Canon.Core/SyntaxNodes/SimpleExpression.cs +++ b/Canon.Core/SyntaxNodes/SimpleExpression.cs @@ -21,6 +21,11 @@ public class SimpleExpression : NonTerminatedSyntaxNode { public override NonTerminatorType Type => NonTerminatorType.SimpleExpression; + /// + /// 是否为条件判断语句 + /// + public bool IsCondition { get; set; } + public override void PreVisit(SyntaxNodeVisitor visitor) { visitor.PreVisit(this); @@ -52,19 +57,17 @@ public class SimpleExpression : NonTerminatedSyntaxNode { if (Children.Count == 1) { - OnTermGenerator?.Invoke(this, new TermGeneratorEventArgs - { - Term = Children[0].Convert() - }); + OnTermGenerator?.Invoke(this, new TermGeneratorEventArgs { Term = Children[0].Convert() }); } else { - OnAddGenerator?.Invoke(this, new AddGeneratorEventArgs - { - Left = Children[0].Convert(), - Operator = Children[1].Convert(), - Right = Children[2].Convert() - }); + OnAddGenerator?.Invoke(this, + new AddGeneratorEventArgs + { + Left = Children[0].Convert(), + Operator = Children[1].Convert(), + Right = Children[2].Convert() + }); } OnTermGenerator = null; diff --git a/Canon.Core/SyntaxNodes/Term.cs b/Canon.Core/SyntaxNodes/Term.cs index d9b0b7e..fc90501 100644 --- a/Canon.Core/SyntaxNodes/Term.cs +++ b/Canon.Core/SyntaxNodes/Term.cs @@ -21,6 +21,11 @@ public class Term : NonTerminatedSyntaxNode { public override NonTerminatorType Type => NonTerminatorType.Term; + /// + /// 是否为条件判断语句 + /// + public bool IsCondition { get; set; } + public override void PreVisit(SyntaxNodeVisitor visitor) { visitor.PreVisit(this); @@ -52,19 +57,17 @@ public class Term : NonTerminatedSyntaxNode { if (Children.Count == 1) { - OnFactorGenerator?.Invoke(this, new FactorGeneratorEventArgs - { - Factor = Children[0].Convert() - }); + OnFactorGenerator?.Invoke(this, new FactorGeneratorEventArgs { Factor = Children[0].Convert() }); } else { - OnMultiplyGenerator?.Invoke(this, new MultiplyGeneratorEventArgs - { - Left = Children[0].Convert(), - Operator = Children[1].Convert(), - Right = Children[2].Convert() - }); + OnMultiplyGenerator?.Invoke(this, + new MultiplyGeneratorEventArgs + { + Left = Children[0].Convert(), + Operator = Children[1].Convert(), + Right = Children[2].Convert() + }); } OnFactorGenerator = null;