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;