misc: 清除冗余的代码
Reviewed-on: PostGuard/Canon#75 Co-authored-by: Lan_G <2911328695@qq.com> Co-committed-by: Lan_G <2911328695@qq.com>
This commit is contained in:
parent
6e8e3885ac
commit
160fafef70
|
@ -1,11 +0,0 @@
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
|
|
||||||
namespace Canon.Core.Abstractions;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 支持生成C语言代码的接口
|
|
||||||
/// </summary>
|
|
||||||
public interface ICCodeGenerator
|
|
||||||
{
|
|
||||||
public void GenerateCCode(CCodeBuilder builder);
|
|
||||||
}
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Canon.Core.SemanticParser;
|
|
||||||
|
|
||||||
namespace Canon.Core.CodeGenerators;
|
namespace Canon.Core.CodeGenerators;
|
||||||
|
|
||||||
|
@ -13,11 +12,6 @@ public class CCodeBuilder
|
||||||
private int _scopeCount = 0;
|
private int _scopeCount = 0;
|
||||||
private string _scopeEmpty = string.Empty;
|
private string _scopeEmpty = string.Empty;
|
||||||
|
|
||||||
public void AddString(string code)
|
|
||||||
{
|
|
||||||
_builder.Append(code);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddLine(string code)
|
public void AddLine(string code)
|
||||||
{
|
{
|
||||||
foreach (string line in code.Split('\n'))
|
foreach (string line in code.Split('\n'))
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
namespace Canon.Core.Exceptions;
|
|
||||||
/// <summary>
|
|
||||||
/// 语义分析中引发的异常
|
|
||||||
/// </summary>
|
|
||||||
public class SemanticException : Exception
|
|
||||||
{
|
|
||||||
public SemanticException() : base() { }
|
|
||||||
|
|
||||||
public SemanticException(string message) : base(message) { }
|
|
||||||
|
|
||||||
public SemanticException(string message, Exception innerException) : base(message, innerException) { }
|
|
||||||
}
|
|
|
@ -1,623 +0,0 @@
|
||||||
using System.Globalization;
|
|
||||||
using Canon.Core.Abstractions;
|
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
|
||||||
using Canon.Core.LexicalParser;
|
|
||||||
using Canon.Core.SyntaxNodes;
|
|
||||||
using BasicType = Canon.Core.SyntaxNodes.BasicType;
|
|
||||||
|
|
||||||
namespace Canon.Core.SemanticParser;
|
|
||||||
|
|
||||||
public class CCodeGenerateVisitor(ICompilerLogger? logger = null) : TypeCheckVisitor(logger)
|
|
||||||
{
|
|
||||||
public CCodeBuilder Builder { get; } = new();
|
|
||||||
|
|
||||||
public override void PreVisit(ProgramStruct programStruct)
|
|
||||||
{
|
|
||||||
base.PreVisit(programStruct);
|
|
||||||
|
|
||||||
Builder.AddString("#include <stdbool.h>\n");
|
|
||||||
Builder.AddString("#include <stdio.h>\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
private string? _constValue;
|
|
||||||
public override void PreVisit(ConstDeclaration constDeclaration)
|
|
||||||
{
|
|
||||||
base.PreVisit(constDeclaration);
|
|
||||||
(_, ConstValue constValue) = constDeclaration.ConstValue;
|
|
||||||
constValue.OnCharacterGenerator += (_, e) =>
|
|
||||||
{
|
|
||||||
_constValue = "'" + e.Token.LiteralValue + "'";
|
|
||||||
};
|
|
||||||
constValue.OnNumberGenerator += (_, e) =>
|
|
||||||
{
|
|
||||||
if (e.IsNegative)
|
|
||||||
{
|
|
||||||
_constValue = "-";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.Token.NumberType == NumberType.Integer)
|
|
||||||
{
|
|
||||||
_constValue += e.Token.ParseAsInteger();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_constValue += e.Token.ParseAsReal();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostVisit(ConstDeclaration constDeclaration)
|
|
||||||
{
|
|
||||||
base.PostVisit(constDeclaration);
|
|
||||||
(IdentifierSemanticToken token, ConstValue constValue) = constDeclaration.ConstValue;
|
|
||||||
|
|
||||||
string cTypeName = TryParseBasicType(constValue.ConstType);
|
|
||||||
Builder.AddString("const " + cTypeName + " " + token.IdentifierName + " = " + _constValue + ";\n");
|
|
||||||
_constValue = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostVisit(VarDeclaration varDeclaration)
|
|
||||||
{
|
|
||||||
base.PostVisit(varDeclaration);
|
|
||||||
|
|
||||||
string idName = varDeclaration.Token.IdentifierName;
|
|
||||||
var type = varDeclaration.IdentifierList.DefinitionType;
|
|
||||||
|
|
||||||
if (type is PascalBasicType)
|
|
||||||
{
|
|
||||||
Builder.AddString(idName + ";\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TryParseArrayType(type, out string _, out string periods);
|
|
||||||
Builder.AddString(idName + periods + ";\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PreVisit(IdentifierList identifierList)
|
|
||||||
{
|
|
||||||
base.PreVisit(identifierList);
|
|
||||||
identifierList.OnTypeGenerator += (_, e) =>
|
|
||||||
{
|
|
||||||
e.TypeSyntaxNode.IsProcedure = identifierList.IsProcedure;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostVisit(IdentifierList identifierList)
|
|
||||||
{
|
|
||||||
base.PostVisit(identifierList);
|
|
||||||
identifierList.OnIdentifierGenerator += (_, e) =>
|
|
||||||
{
|
|
||||||
if(!identifierList.IsProcedure)
|
|
||||||
{
|
|
||||||
string periods = ""; //如果是数组定义,需要每个标识符后带上
|
|
||||||
if (e.IdentifierList.DefinitionType is PascalArrayType pascalArrayType)
|
|
||||||
{
|
|
||||||
TryParseArrayType(pascalArrayType, out string _, out string periods0);
|
|
||||||
periods = periods0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Builder.AddString(e.IdentifierToken.IdentifierName + periods + ", ");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public override void PreVisit(TypeSyntaxNode typeSyntaxNode)
|
|
||||||
{
|
|
||||||
base.PreVisit(typeSyntaxNode);
|
|
||||||
typeSyntaxNode.OnBasicTypeGenerator += (_, e) =>
|
|
||||||
{
|
|
||||||
e.BasicType.IsProcedure = typeSyntaxNode.IsProcedure;
|
|
||||||
};
|
|
||||||
typeSyntaxNode.OnArrayTypeGenerator += (_, e) =>
|
|
||||||
{
|
|
||||||
e.BasicType.IsProcedure = typeSyntaxNode.IsProcedure;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostVisit(BasicType basicType)
|
|
||||||
{
|
|
||||||
base.PostVisit(basicType);
|
|
||||||
if (!basicType.IsProcedure)
|
|
||||||
{
|
|
||||||
Builder.AddString(TryParseBasicType(basicType.PascalType) + " ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public override void PostVisit(SubprogramHead subprogramHead)
|
|
||||||
{
|
|
||||||
base.PostVisit(subprogramHead);
|
|
||||||
|
|
||||||
string subprogramName = subprogramHead.SubprogramName.IdentifierName;
|
|
||||||
//只需特判过程,函数的返回值类型已在basicType节点上生成
|
|
||||||
if (subprogramHead.IsProcedure)
|
|
||||||
{
|
|
||||||
Builder.AddString("void ");
|
|
||||||
}
|
|
||||||
Builder.AddString(subprogramName);
|
|
||||||
//生成参数列表
|
|
||||||
Builder.AddString("(");
|
|
||||||
List<string> parametersInfo = new();
|
|
||||||
|
|
||||||
foreach (List<Symbol> children in ValueParameters)
|
|
||||||
{
|
|
||||||
foreach (Symbol symbol in children.AsEnumerable().Reverse())
|
|
||||||
{
|
|
||||||
if (symbol.SymbolType is PascalBasicType pascalType)
|
|
||||||
{
|
|
||||||
string typeName = TryParseBasicType(pascalType);
|
|
||||||
if (symbol.Reference)
|
|
||||||
{
|
|
||||||
parametersInfo.Add(typeName + "* " + symbol.SymbolName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
parametersInfo.Add(typeName + " " + symbol.SymbolName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TryParseArrayType(symbol.SymbolType, out string basicTypeName, out string periods);
|
|
||||||
parametersInfo.Add(string.Concat(basicTypeName, " ", symbol.SymbolName, "[]",
|
|
||||||
periods.Substring(periods.IndexOf(']') + 1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Builder.AddString(string.Join(", ", parametersInfo));
|
|
||||||
Builder.AddString(")\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
private string _subprogramName = "";
|
|
||||||
public override void PreVisit(Subprogram subprogram)
|
|
||||||
{
|
|
||||||
base.PreVisit(subprogram);
|
|
||||||
_subprogramName = subprogram.Head.SubprogramName.IdentifierName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostVisit(Subprogram subprogram)
|
|
||||||
{
|
|
||||||
base.PostVisit(subprogram);
|
|
||||||
if (subprogram.Head.IsProcedure)
|
|
||||||
{
|
|
||||||
Builder.AddString("\n}\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//为函数生成返回语句
|
|
||||||
Builder.AddString("return " + subprogram.Head.SubprogramName.IdentifierName + ";\n}\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PreVisit(SubprogramBody subprogramBody)
|
|
||||||
{
|
|
||||||
base.PreVisit(subprogramBody);
|
|
||||||
Builder.AddString("{\n");
|
|
||||||
//生成函数返回值变量
|
|
||||||
SymbolTable.TryGetSymbol(_subprogramName, out var symbol);
|
|
||||||
if (symbol is null || symbol.SymbolType is not PascalBasicType)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Builder.AddString(TryParseBasicType(symbol.SymbolType.Convert<PascalType>()) + " " + _subprogramName + ";\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PreVisit(ProcedureCall procedureCall)
|
|
||||||
{
|
|
||||||
base.PreVisit(procedureCall);
|
|
||||||
string procedureName = procedureCall.ProcedureId.IdentifierName;
|
|
||||||
|
|
||||||
if (procedureName == "read")
|
|
||||||
{
|
|
||||||
Builder.AddString("scanf(\"%d\", &");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (procedureName == "write")
|
|
||||||
{
|
|
||||||
Builder.AddString("printf(\"%d\", ");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Builder.AddString(procedureName + "(");
|
|
||||||
|
|
||||||
procedureCall.OnParameterGenerator += (_, e) =>
|
|
||||||
{
|
|
||||||
string procedureIdName = procedureCall.ProcedureId.IdentifierName;
|
|
||||||
|
|
||||||
SymbolTable.TryGetParent(out var parentTable);
|
|
||||||
parentTable ??= SymbolTable;
|
|
||||||
|
|
||||||
parentTable.TryGetSymbol(procedureIdName, out var symbol);
|
|
||||||
|
|
||||||
if (symbol is null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
e.Parameters.ParameterTypes.AddRange(symbol.SymbolType.Convert<PascalFunctionType>().Parameters);
|
|
||||||
e.Parameters.Expression.LastParam = true;
|
|
||||||
e.Parameters.IsParamList = true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostVisit(ProcedureCall procedureCall)
|
|
||||||
{
|
|
||||||
base.PostVisit(procedureCall);
|
|
||||||
Builder.AddString(")");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PreVisit(ProgramBody programBody)
|
|
||||||
{
|
|
||||||
base.PreVisit(programBody);
|
|
||||||
//当子函数全部定义完成时,生成main函数头
|
|
||||||
programBody.CompoundStatement.IsMain = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostVisit(CompoundStatement compoundStatement)
|
|
||||||
{
|
|
||||||
base.PostVisit(compoundStatement);
|
|
||||||
if (compoundStatement.IsMain)
|
|
||||||
{
|
|
||||||
Builder.AddString("\nreturn 0;\n");
|
|
||||||
}
|
|
||||||
Builder.AddString("}\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PreVisit(CompoundStatement compoundStatement)
|
|
||||||
{
|
|
||||||
base.PreVisit(compoundStatement);
|
|
||||||
if (compoundStatement.IsMain)
|
|
||||||
{
|
|
||||||
Builder.AddString("int main()\n");
|
|
||||||
}
|
|
||||||
Builder.AddString("{\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PreVisit(Statement statement)
|
|
||||||
{
|
|
||||||
base.PreVisit(statement);
|
|
||||||
statement.OnForGenerator += (_, e) =>
|
|
||||||
{
|
|
||||||
e.Begin.Iterator = e.Iterator;
|
|
||||||
e.Begin.IsForConditionBegin = true;
|
|
||||||
e.End.Iterator = e.Iterator;
|
|
||||||
e.End.IsForConditionEnd = true;
|
|
||||||
};
|
|
||||||
statement.OnAssignGenerator += (_, e) =>
|
|
||||||
{
|
|
||||||
e.Expression.IsAssign = true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostVisit(Statement statement)
|
|
||||||
{
|
|
||||||
base.PostVisit(statement);
|
|
||||||
Builder.AddString(";\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PreVisit(Variable variable)
|
|
||||||
{
|
|
||||||
base.PreVisit(variable);
|
|
||||||
|
|
||||||
SymbolTable.TryGetSymbol(variable.Identifier.IdentifierName, out var symbol);
|
|
||||||
if (symbol == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (symbol.Reference)
|
|
||||||
{
|
|
||||||
Builder.AddString("(*" + variable.Identifier.IdentifierName + ")");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Builder.AddString(variable.Identifier.IdentifierName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (symbol.SymbolType is PascalArrayType)
|
|
||||||
{
|
|
||||||
//解析数组类型,获取左边界列表
|
|
||||||
List<int> leftBounds = new();
|
|
||||||
PascalType curType = symbol.SymbolType;
|
|
||||||
while (curType is not PascalBasicType)
|
|
||||||
{
|
|
||||||
leftBounds.Add(curType.Convert<PascalArrayType>().Begin);
|
|
||||||
curType = curType.Convert<PascalArrayType>().ElementType;
|
|
||||||
}
|
|
||||||
|
|
||||||
//将数组维度信息向下传递
|
|
||||||
variable.VarPart.LeftBounds.AddRange(leftBounds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PreVisit(IdentifierVarPart identifierVarPart)
|
|
||||||
{
|
|
||||||
base.PreVisit(identifierVarPart);
|
|
||||||
identifierVarPart.OnIndexGenerator += (_, e) =>
|
|
||||||
{
|
|
||||||
e.IndexParameters.IsIndex = true;
|
|
||||||
e.IndexParameters.LeftBounds = identifierVarPart.LeftBounds;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PreVisit(ExpressionList expressionList)
|
|
||||||
{
|
|
||||||
base.PreVisit(expressionList);
|
|
||||||
|
|
||||||
if (expressionList.IsIndex)
|
|
||||||
{
|
|
||||||
expressionList.Expression.LeftBound = expressionList.LeftBounds.Last();
|
|
||||||
expressionList.Expression.IsIndex = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expressionList.IsParamList)
|
|
||||||
{
|
|
||||||
expressionList.Expression.ReferenceParam = expressionList.ParameterTypes.Last().IsVar;
|
|
||||||
expressionList.Expression.IsParam = true;
|
|
||||||
}
|
|
||||||
expressionList.OnExpressionList += (_, e) =>
|
|
||||||
{
|
|
||||||
if (expressionList.IsIndex)
|
|
||||||
{
|
|
||||||
e.ExpressionList.IsIndex = true;
|
|
||||||
expressionList.LeftBounds.RemoveAt(expressionList.LeftBounds.Count - 1);
|
|
||||||
e.ExpressionList.LeftBounds = expressionList.LeftBounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expressionList.IsParamList)
|
|
||||||
{
|
|
||||||
e.ExpressionList.IsParamList = true;
|
|
||||||
for (int i = 0; i < expressionList.ParameterTypes.Count - 1; i++)
|
|
||||||
{
|
|
||||||
e.ExpressionList.ParameterTypes.Add(expressionList.ParameterTypes[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PreVisit(Expression expression)
|
|
||||||
{
|
|
||||||
base.PreVisit(expression);
|
|
||||||
if (expression.IsIndex)
|
|
||||||
{
|
|
||||||
Builder.AddString("[");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expression.IsForConditionBegin)
|
|
||||||
{
|
|
||||||
Builder.AddString("for(" + expression.Iterator.IdentifierName + " = ");
|
|
||||||
}
|
|
||||||
if (expression.IsForConditionEnd)
|
|
||||||
{
|
|
||||||
Builder.AddString(expression.Iterator.IdentifierName + " <= ");
|
|
||||||
}
|
|
||||||
if (expression.IsAssign)
|
|
||||||
{
|
|
||||||
Builder.AddString(" = ");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expression.ReferenceParam)
|
|
||||||
{
|
|
||||||
Builder.AddString("&");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostVisit(Expression expression)
|
|
||||||
{
|
|
||||||
base.PostVisit(expression);
|
|
||||||
if (expression.IsIndex)
|
|
||||||
{
|
|
||||||
//数组下标减去当前维度的左边界
|
|
||||||
Builder.AddString("-" + expression.LeftBound + "]");
|
|
||||||
}
|
|
||||||
if (expression.IsForConditionEnd)
|
|
||||||
{
|
|
||||||
Builder.AddString("; " + expression.Iterator.IdentifierName + "++)");
|
|
||||||
}
|
|
||||||
if (expression is { IsParam: true, LastParam: false })
|
|
||||||
{
|
|
||||||
Builder.AddString(", ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostVisit(Factor factor)
|
|
||||||
{
|
|
||||||
base.PostVisit(factor);
|
|
||||||
factor.OnNumberGenerator += (_, e) =>
|
|
||||||
{
|
|
||||||
var token = e.Token;
|
|
||||||
string num = token.NumberType == NumberType.Integer ? token.ParseAsInteger().ToString() :
|
|
||||||
token.ParseAsReal().ToString(CultureInfo.InvariantCulture);
|
|
||||||
Builder.AddString(num);
|
|
||||||
};
|
|
||||||
factor.OnNotGenerator += (_, _) =>
|
|
||||||
{
|
|
||||||
Builder.AddString(")");
|
|
||||||
};
|
|
||||||
factor.OnUminusGenerator += (_, _) =>
|
|
||||||
{
|
|
||||||
Builder.AddString(")");
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PreVisit(Factor factor)
|
|
||||||
{
|
|
||||||
base.PreVisit(factor);
|
|
||||||
|
|
||||||
factor.OnNotGenerator += (_, _) =>
|
|
||||||
{
|
|
||||||
Builder.AddString("(~");
|
|
||||||
};
|
|
||||||
factor.OnUminusGenerator += (_, _) =>
|
|
||||||
{
|
|
||||||
Builder.AddString("(-");
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostVisit(MultiplyOperator multiplyOperator)
|
|
||||||
{
|
|
||||||
base.PostVisit(multiplyOperator);
|
|
||||||
if (multiplyOperator.OperatorToken.TokenType == SemanticTokenType.Operator)
|
|
||||||
{
|
|
||||||
var operatorType = multiplyOperator.OperatorToken.Convert<OperatorSemanticToken>().OperatorType;
|
|
||||||
if (operatorType == OperatorType.Multiply)
|
|
||||||
{
|
|
||||||
Builder.AddString(" * ");
|
|
||||||
}
|
|
||||||
else if (operatorType == OperatorType.Divide)
|
|
||||||
{
|
|
||||||
//实数除法,需要将操作数强转为double
|
|
||||||
Builder.AddString(" /(double)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var keywordType = multiplyOperator.OperatorToken.Convert<KeywordSemanticToken>().KeywordType;
|
|
||||||
switch (keywordType)
|
|
||||||
{
|
|
||||||
case KeywordType.And:
|
|
||||||
Builder.AddString(" && ");
|
|
||||||
break;
|
|
||||||
case KeywordType.Mod:
|
|
||||||
Builder.AddString(" % ");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Builder.AddString(" / ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostVisit(AddOperator addOperator)
|
|
||||||
{
|
|
||||||
base.PostVisit(addOperator);
|
|
||||||
var token = addOperator.OperatorToken;
|
|
||||||
if (token.TokenType == SemanticTokenType.Operator)
|
|
||||||
{
|
|
||||||
var operatorType = token.Convert<OperatorSemanticToken>().OperatorType;
|
|
||||||
if (operatorType == OperatorType.Plus)
|
|
||||||
{
|
|
||||||
Builder.AddString(" + ");
|
|
||||||
}
|
|
||||||
else if (operatorType == OperatorType.Minus)
|
|
||||||
{
|
|
||||||
Builder.AddString(" - ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Builder.AddString(" || ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostVisit(RelationOperator relationOperator)
|
|
||||||
{
|
|
||||||
base.PostVisit(relationOperator);
|
|
||||||
var operatorType = relationOperator.OperatorToken.Convert<OperatorSemanticToken>().OperatorType;
|
|
||||||
switch (operatorType)
|
|
||||||
{
|
|
||||||
case OperatorType.Equal:
|
|
||||||
Builder.AddString(" == ");
|
|
||||||
break;
|
|
||||||
case OperatorType.Greater:
|
|
||||||
Builder.AddString(" > ");
|
|
||||||
break;
|
|
||||||
case OperatorType.Less:
|
|
||||||
Builder.AddString(" < ");
|
|
||||||
break;
|
|
||||||
case OperatorType.GreaterEqual:
|
|
||||||
Builder.AddString(" >= ");
|
|
||||||
break;
|
|
||||||
case OperatorType.LessEqual:
|
|
||||||
Builder.AddString(" <= ");
|
|
||||||
break;
|
|
||||||
case OperatorType.NotEqual:
|
|
||||||
Builder.AddString(" != ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void PostVisit(TerminatedSyntaxNode terminatedSyntaxNode)
|
|
||||||
{
|
|
||||||
base.PostVisit(terminatedSyntaxNode);
|
|
||||||
string literalValue = terminatedSyntaxNode.Token.LiteralValue;
|
|
||||||
switch (literalValue)
|
|
||||||
{
|
|
||||||
case "if":
|
|
||||||
Builder.AddString("if(");
|
|
||||||
break;
|
|
||||||
case "then":
|
|
||||||
Builder.AddString(")\n");
|
|
||||||
break;
|
|
||||||
case "else":
|
|
||||||
Builder.AddString("else\n");
|
|
||||||
break;
|
|
||||||
case "to":
|
|
||||||
Builder.AddString("; ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 尝试将pascalBasicType解析成C语言的基本类型
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>C语言形式的基本类型名</returns>
|
|
||||||
/// <exception cref="InvalidOperationException"></exception>
|
|
||||||
private string TryParseBasicType(PascalType pascalType)
|
|
||||||
{
|
|
||||||
if (pascalType is PascalBasicType basicType)
|
|
||||||
{
|
|
||||||
if (basicType == PascalBasicType.Integer)
|
|
||||||
{
|
|
||||||
return "int";
|
|
||||||
}
|
|
||||||
if (basicType == PascalBasicType.Real)
|
|
||||||
{
|
|
||||||
return "double";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (basicType == PascalBasicType.Character)
|
|
||||||
{
|
|
||||||
return "char";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (basicType == PascalBasicType.Boolean)
|
|
||||||
{
|
|
||||||
return "bool";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (basicType == PascalBasicType.Void)
|
|
||||||
{
|
|
||||||
return "void";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InvalidOperationException("Not a basic type");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 尝试解析Pascal数组类型
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pascalType"></param>
|
|
||||||
/// <param name="basicTypeName">数组实际存储的元素类型</param>
|
|
||||||
/// <param name="periods">数组下标定义</param>
|
|
||||||
private void TryParseArrayType(PascalType pascalType, out string basicTypeName, out string periods)
|
|
||||||
{
|
|
||||||
periods = "";
|
|
||||||
PascalType curType = pascalType;
|
|
||||||
//依次处理数组每一维
|
|
||||||
while (curType is PascalArrayType pascalArrayType)
|
|
||||||
{
|
|
||||||
int begin = pascalArrayType.Begin;
|
|
||||||
int end = pascalArrayType.End;
|
|
||||||
//C语言数组下标从0开始,所以下标要减去begin
|
|
||||||
periods += "[" + (end - begin + 1) + "]";
|
|
||||||
curType = pascalArrayType.ElementType;
|
|
||||||
}
|
|
||||||
|
|
||||||
basicTypeName = TryParseBasicType(curType);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -87,11 +87,9 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito
|
||||||
switch (e.Token.NumberType)
|
switch (e.Token.NumberType)
|
||||||
{
|
{
|
||||||
case NumberType.Integer:
|
case NumberType.Integer:
|
||||||
factor.FactorType = PascalBasicType.Integer;
|
|
||||||
factor.VariableType = PascalBasicType.Integer;
|
factor.VariableType = PascalBasicType.Integer;
|
||||||
break;
|
break;
|
||||||
case NumberType.Real:
|
case NumberType.Real:
|
||||||
factor.FactorType = PascalBasicType.Real;
|
|
||||||
factor.VariableType = PascalBasicType.Real;
|
factor.VariableType = PascalBasicType.Real;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -100,14 +98,12 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito
|
||||||
// factor -> true | false
|
// factor -> true | false
|
||||||
factor.OnBooleanGenerator += (_, _) =>
|
factor.OnBooleanGenerator += (_, _) =>
|
||||||
{
|
{
|
||||||
factor.FactorType = PascalBasicType.Boolean;
|
|
||||||
factor.VariableType = PascalBasicType.Boolean;
|
factor.VariableType = PascalBasicType.Boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
// factor -> variable
|
// factor -> variable
|
||||||
factor.OnVariableGenerator += (_, e) =>
|
factor.OnVariableGenerator += (_, e) =>
|
||||||
{
|
{
|
||||||
factor.FactorType = e.Variable.VariableType;
|
|
||||||
factor.VariableType = e.Variable.VariableType;
|
factor.VariableType = e.Variable.VariableType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -115,7 +111,6 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito
|
||||||
// factor -> (expression)
|
// factor -> (expression)
|
||||||
factor.OnParethnesisGenerator += (_, e) =>
|
factor.OnParethnesisGenerator += (_, e) =>
|
||||||
{
|
{
|
||||||
factor.FactorType = e.Expression.ExpressionType;
|
|
||||||
factor.VariableType = e.Expression.VariableType;
|
factor.VariableType = e.Expression.VariableType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -126,7 +121,6 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito
|
||||||
{
|
{
|
||||||
if (functionType.ReturnType != PascalBasicType.Void)
|
if (functionType.ReturnType != PascalBasicType.Void)
|
||||||
{
|
{
|
||||||
factor.FactorType = functionType.ReturnType;
|
|
||||||
factor.VariableType = functionType.ReturnType;
|
factor.VariableType = functionType.ReturnType;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -137,28 +131,24 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
factor.FactorType = PascalBasicType.Void;
|
|
||||||
factor.VariableType = PascalBasicType.Void;
|
factor.VariableType = PascalBasicType.Void;
|
||||||
};
|
};
|
||||||
|
|
||||||
// factor -> not factor
|
// factor -> not factor
|
||||||
factor.OnNotGenerator += (_, e) =>
|
factor.OnNotGenerator += (_, e) =>
|
||||||
{
|
{
|
||||||
factor.FactorType = e.Factor.FactorType;
|
|
||||||
factor.VariableType = e.Factor.VariableType;
|
factor.VariableType = e.Factor.VariableType;
|
||||||
};
|
};
|
||||||
|
|
||||||
// factor -> uminus factor
|
// factor -> uminus factor
|
||||||
factor.OnUminusGenerator += (_, e) =>
|
factor.OnUminusGenerator += (_, e) =>
|
||||||
{
|
{
|
||||||
factor.FactorType = e.Factor.FactorType;
|
|
||||||
factor.VariableType = e.Factor.VariableType;
|
factor.VariableType = e.Factor.VariableType;
|
||||||
};
|
};
|
||||||
|
|
||||||
// factor -> plus factor
|
// factor -> plus factor
|
||||||
factor.OnPlusGenerator += (_, e) =>
|
factor.OnPlusGenerator += (_, e) =>
|
||||||
{
|
{
|
||||||
factor.FactorType = e.Factor.FactorType;
|
|
||||||
factor.VariableType = e.Factor.VariableType;
|
factor.VariableType = e.Factor.VariableType;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -169,16 +159,14 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito
|
||||||
|
|
||||||
term.OnFactorGenerator += (_, e) =>
|
term.OnFactorGenerator += (_, e) =>
|
||||||
{
|
{
|
||||||
term.TermType = e.Factor.FactorType;
|
|
||||||
term.VariableType = e.Factor.VariableType;
|
term.VariableType = e.Factor.VariableType;
|
||||||
};
|
};
|
||||||
|
|
||||||
term.OnMultiplyGenerator += (_, e) =>
|
term.OnMultiplyGenerator += (_, e) =>
|
||||||
{
|
{
|
||||||
if (PascalType.IsCalculatable(e.Left.TermType) && PascalType.IsCalculatable(e.Right.FactorType))
|
if (PascalType.IsCalculatable(e.Left.VariableType) && PascalType.IsCalculatable(e.Right.VariableType))
|
||||||
{
|
{
|
||||||
term.TermType = e.Left.TermType + e.Right.FactorType;
|
term.VariableType = e.Left.VariableType + e.Right.VariableType;
|
||||||
term.VariableType = e.Left.TermType + e.Right.FactorType;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,15 +181,13 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito
|
||||||
|
|
||||||
simpleExpression.OnTermGenerator += (_, e) =>
|
simpleExpression.OnTermGenerator += (_, e) =>
|
||||||
{
|
{
|
||||||
simpleExpression.SimpleExpressionType = e.Term.TermType;
|
|
||||||
simpleExpression.VariableType = e.Term.VariableType;
|
simpleExpression.VariableType = e.Term.VariableType;
|
||||||
};
|
};
|
||||||
|
|
||||||
simpleExpression.OnAddGenerator += (_, e) =>
|
simpleExpression.OnAddGenerator += (_, e) =>
|
||||||
{
|
{
|
||||||
if (PascalType.IsCalculatable(e.Left.SimpleExpressionType) && PascalType.IsCalculatable(e.Right.TermType))
|
if (PascalType.IsCalculatable(e.Left.VariableType) && PascalType.IsCalculatable(e.Right.VariableType))
|
||||||
{
|
{
|
||||||
simpleExpression.SimpleExpressionType = e.Left.SimpleExpressionType + e.Right.TermType;
|
|
||||||
simpleExpression.VariableType = e.Left.VariableType + e.Right.VariableType;
|
simpleExpression.VariableType = e.Left.VariableType + e.Right.VariableType;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -217,13 +203,11 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito
|
||||||
|
|
||||||
expression.OnSimpleExpressionGenerator += (_, e) =>
|
expression.OnSimpleExpressionGenerator += (_, e) =>
|
||||||
{
|
{
|
||||||
expression.ExpressionType = e.SimpleExpression.SimpleExpressionType;
|
|
||||||
expression.VariableType = e.SimpleExpression.VariableType;
|
expression.VariableType = e.SimpleExpression.VariableType;
|
||||||
};
|
};
|
||||||
|
|
||||||
expression.OnRelationGenerator += (_, _) =>
|
expression.OnRelationGenerator += (_, _) =>
|
||||||
{
|
{
|
||||||
expression.ExpressionType = PascalBasicType.Boolean;
|
|
||||||
expression.VariableType = PascalBasicType.Boolean;
|
expression.VariableType = PascalBasicType.Boolean;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -468,7 +452,7 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查ExpressionA是否为Integer
|
// 检查ExpressionA是否为Integer
|
||||||
if (e.Begin.ExpressionType != PascalBasicType.Integer)
|
if (e.Begin.VariableType != PascalBasicType.Integer)
|
||||||
{
|
{
|
||||||
IsError = true;
|
IsError = true;
|
||||||
logger?.LogError("The loop begin parameter is not integer.");
|
logger?.LogError("The loop begin parameter is not integer.");
|
||||||
|
@ -476,7 +460,7 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查ExpressionB是否为Integer
|
// 检查ExpressionB是否为Integer
|
||||||
if (e.End.ExpressionType != PascalBasicType.Integer)
|
if (e.End.VariableType != PascalBasicType.Integer)
|
||||||
{
|
{
|
||||||
IsError = true;
|
IsError = true;
|
||||||
logger?.LogError("The loop end parameter is not integer.");
|
logger?.LogError("The loop end parameter is not integer.");
|
||||||
|
@ -487,11 +471,11 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito
|
||||||
statement.OnIfGenerator += (_, e) =>
|
statement.OnIfGenerator += (_, e) =>
|
||||||
{
|
{
|
||||||
// 条件是否为Boolean
|
// 条件是否为Boolean
|
||||||
if (e.Condition.ExpressionType != PascalBasicType.Boolean)
|
if (e.Condition.VariableType != PascalBasicType.Boolean)
|
||||||
{
|
{
|
||||||
IsError = true;
|
IsError = true;
|
||||||
logger?.LogError("Expect '{}' but '{}'.", PascalBasicType.Boolean.TypeName,
|
logger?.LogError("Expect '{}' but '{}'.", PascalBasicType.Boolean.TypeName,
|
||||||
e.Condition.ExpressionType.ToString());
|
e.Condition.VariableType.ToString());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -566,11 +550,11 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito
|
||||||
{
|
{
|
||||||
foreach (Expression expression in e.IndexParameters.Expressions)
|
foreach (Expression expression in e.IndexParameters.Expressions)
|
||||||
{
|
{
|
||||||
if (expression.ExpressionType != PascalBasicType.Integer)
|
if (expression.VariableType != PascalBasicType.Integer)
|
||||||
{
|
{
|
||||||
IsError = true;
|
IsError = true;
|
||||||
logger?.LogError("Index of array expect 'int' but '{}'",
|
logger?.LogError("Index of array expect 'int' but '{}'",
|
||||||
expression.ExpressionType.ToString());
|
expression.VariableType.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,11 +636,11 @@ public class TypeCheckVisitor(ICompilerLogger? logger = null) : SyntaxNodeVisito
|
||||||
foreach ((Expression expression, PascalParameterType parameterType) in parameters.Zip(targetFunctionType
|
foreach ((Expression expression, PascalParameterType parameterType) in parameters.Zip(targetFunctionType
|
||||||
.Parameters))
|
.Parameters))
|
||||||
{
|
{
|
||||||
if (expression.ExpressionType != parameterType.ParameterType)
|
if (expression.VariableType != parameterType.ParameterType)
|
||||||
{
|
{
|
||||||
IsError = true;
|
IsError = true;
|
||||||
logger?.LogError("Parameter expect '{}' but '{}' is provided.",
|
logger?.LogError("Parameter expect '{}' but '{}' is provided.",
|
||||||
parameterType.ParameterType, expression.ExpressionType);
|
parameterType.ParameterType, expression.VariableType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Security;
|
|
||||||
using Canon.Core.Exceptions;
|
|
||||||
|
|
||||||
namespace Canon.Core.SemanticParser;
|
namespace Canon.Core.SemanticParser;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
using Canon.Core.LexicalParser;
|
using Canon.Core.LexicalParser;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
using Canon.Core.LexicalParser;
|
using Canon.Core.LexicalParser;
|
||||||
using Canon.Core.SemanticParser;
|
using Canon.Core.SemanticParser;
|
||||||
|
@ -10,7 +9,6 @@ public class BasicType : NonTerminatedSyntaxNode
|
||||||
{
|
{
|
||||||
public override NonTerminatorType Type => NonTerminatorType.BasicType;
|
public override NonTerminatorType Type => NonTerminatorType.BasicType;
|
||||||
|
|
||||||
public bool IsProcedure;
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// BasicType代表的Pascal类型
|
/// BasicType代表的Pascal类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
using Canon.Core.LexicalParser;
|
using Canon.Core.LexicalParser;
|
||||||
using Canon.Core.SemanticParser;
|
using Canon.Core.SemanticParser;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
|
|
||||||
namespace Canon.Core.SyntaxNodes;
|
namespace Canon.Core.SyntaxNodes;
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
using Canon.Core.LexicalParser;
|
|
||||||
using Canon.Core.SemanticParser;
|
|
||||||
|
|
||||||
namespace Canon.Core.SyntaxNodes;
|
namespace Canon.Core.SyntaxNodes;
|
||||||
|
|
||||||
|
@ -36,21 +33,6 @@ public class Expression : NonTerminatedSyntaxNode
|
||||||
RaiseEvent();
|
RaiseEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsParam; //是否为传参
|
|
||||||
|
|
||||||
public bool ReferenceParam; //是否为引用传参
|
|
||||||
|
|
||||||
public bool LastParam; //是否为传参列表里最后一个参数
|
|
||||||
/// <summary>
|
|
||||||
/// 是否为数组下标
|
|
||||||
/// </summary>
|
|
||||||
public bool IsIndex { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 当前表达式对应的数组下标维度的左边界
|
|
||||||
/// </summary>
|
|
||||||
public int LeftBound;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否为FOR语句中的起始语句
|
/// 是否为FOR语句中的起始语句
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -60,32 +42,12 @@ public class Expression : NonTerminatedSyntaxNode
|
||||||
/// 是否为FOR语句中的结束语句
|
/// 是否为FOR语句中的结束语句
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsForConditionEnd { get; set; }
|
public bool IsForConditionEnd { get; set; }
|
||||||
public bool IsAssign { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否为IF语句中的条件语句
|
/// 是否为IF语句中的条件语句
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsIfCondition { get; set; }
|
public bool IsIfCondition { get; set; }
|
||||||
|
|
||||||
private IdentifierSemanticToken? _iterator;
|
|
||||||
|
|
||||||
public IdentifierSemanticToken Iterator
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_iterator is null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _iterator;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_iterator = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 直接赋值产生式的事件
|
/// 直接赋值产生式的事件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -96,25 +58,6 @@ public class Expression : NonTerminatedSyntaxNode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<RelationGeneratorEventArgs>? OnRelationGenerator;
|
public event EventHandler<RelationGeneratorEventArgs>? OnRelationGenerator;
|
||||||
|
|
||||||
private PascalType? _expressionType;
|
|
||||||
|
|
||||||
public PascalType ExpressionType
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_expressionType is null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _expressionType;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_expressionType = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Expression Create(List<SyntaxNodeBase> children)
|
public static Expression Create(List<SyntaxNodeBase> children)
|
||||||
{
|
{
|
||||||
return new Expression { Children = children };
|
return new Expression { Children = children };
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
using Canon.Core.SemanticParser;
|
|
||||||
|
|
||||||
namespace Canon.Core.SyntaxNodes;
|
namespace Canon.Core.SyntaxNodes;
|
||||||
|
|
||||||
|
@ -18,23 +17,6 @@ public class ExpressionList : NonTerminatedSyntaxNode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<Expression> Expressions { get; } = [];
|
public List<Expression> Expressions { get; } = [];
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否为传参列表
|
|
||||||
/// </summary>
|
|
||||||
public bool IsParamList;
|
|
||||||
|
|
||||||
public List<PascalParameterType> ParameterTypes { get; } = [];
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否为数组下标索引
|
|
||||||
/// </summary>
|
|
||||||
public bool IsIndex { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 数组左边界列表
|
|
||||||
/// </summary>
|
|
||||||
public List<int> LeftBounds = new();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前ExpressionList中的Expression定义
|
/// 当前ExpressionList中的Expression定义
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
using Canon.Core.LexicalParser;
|
using Canon.Core.LexicalParser;
|
||||||
using Canon.Core.SemanticParser;
|
|
||||||
|
|
||||||
namespace Canon.Core.SyntaxNodes;
|
namespace Canon.Core.SyntaxNodes;
|
||||||
|
|
||||||
|
@ -103,22 +102,6 @@ public class Factor : NonTerminatedSyntaxNode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<ProcedureCallGeneratorEventArgs>? OnProcedureCallGenerator;
|
public event EventHandler<ProcedureCallGeneratorEventArgs>? OnProcedureCallGenerator;
|
||||||
|
|
||||||
private PascalType? _factorType;
|
|
||||||
|
|
||||||
public PascalType FactorType
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_factorType is null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _factorType;
|
|
||||||
}
|
|
||||||
set { _factorType = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Factor Create(List<SyntaxNodeBase> children)
|
public static Factor Create(List<SyntaxNodeBase> children)
|
||||||
{
|
{
|
||||||
return new Factor { Children = children };
|
return new Factor { Children = children };
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
using Canon.Core.SemanticParser;
|
|
||||||
|
|
||||||
namespace Canon.Core.SyntaxNodes;
|
namespace Canon.Core.SyntaxNodes;
|
||||||
|
|
||||||
|
@ -18,11 +17,6 @@ public class IdentifierVarPart : NonTerminatedSyntaxNode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int IndexCount { get; set; }
|
public int IndexCount { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 数组左边界列表
|
|
||||||
/// </summary>
|
|
||||||
public List<int> LeftBounds = new();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 索引中的表达式
|
/// 索引中的表达式
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
using Canon.Core.LexicalParser;
|
using Canon.Core.LexicalParser;
|
||||||
|
|
||||||
|
|
|
@ -12,12 +12,6 @@ public class Parameter : NonTerminatedSyntaxNode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsVar { get; private init; }
|
public bool IsVar { get; private init; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 声明的变量名称
|
|
||||||
/// </summary>
|
|
||||||
public ValueParameter ValueParameter =>
|
|
||||||
IsVar ? Children[0].Convert<VarParameter>().ValueParameter : Children[0].Convert<ValueParameter>();
|
|
||||||
|
|
||||||
public override void PreVisit(SyntaxNodeVisitor visitor)
|
public override void PreVisit(SyntaxNodeVisitor visitor)
|
||||||
{
|
{
|
||||||
visitor.PreVisit(this);
|
visitor.PreVisit(this);
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
|
|
||||||
namespace Canon.Core.SyntaxNodes;
|
namespace Canon.Core.SyntaxNodes;
|
||||||
|
@ -8,21 +7,6 @@ public class ProgramBody : NonTerminatedSyntaxNode
|
||||||
{
|
{
|
||||||
public override NonTerminatorType Type => NonTerminatorType.ProgramBody;
|
public override NonTerminatorType Type => NonTerminatorType.ProgramBody;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 常量声明
|
|
||||||
/// </summary>
|
|
||||||
public ConstDeclarations ConstDeclarations => Children[0].Convert<ConstDeclarations>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 变量声明
|
|
||||||
/// </summary>
|
|
||||||
public VarDeclarations VarDeclarations => Children[1].Convert<VarDeclarations>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 子程序声明
|
|
||||||
/// </summary>
|
|
||||||
public SubprogramDeclarations SubprogramDeclarations => Children[2].Convert<SubprogramDeclarations>();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 语句声明
|
/// 语句声明
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
|
|
||||||
namespace Canon.Core.SyntaxNodes;
|
namespace Canon.Core.SyntaxNodes;
|
||||||
|
@ -13,11 +12,6 @@ public class ProgramStruct : NonTerminatedSyntaxNode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ProgramHead Head => Children[0].Convert<ProgramHead>();
|
public ProgramHead Head => Children[0].Convert<ProgramHead>();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 程序体
|
|
||||||
/// </summary>
|
|
||||||
public ProgramBody Body => Children[2].Convert<ProgramBody>();
|
|
||||||
|
|
||||||
public override void PreVisit(SyntaxNodeVisitor visitor)
|
public override void PreVisit(SyntaxNodeVisitor visitor)
|
||||||
{
|
{
|
||||||
visitor.PreVisit(this);
|
visitor.PreVisit(this);
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
using Canon.Core.LexicalParser;
|
using Canon.Core.LexicalParser;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
using Canon.Core.SemanticParser;
|
|
||||||
|
|
||||||
namespace Canon.Core.SyntaxNodes;
|
namespace Canon.Core.SyntaxNodes;
|
||||||
|
|
||||||
|
@ -45,25 +43,6 @@ public class SimpleExpression : NonTerminatedSyntaxNode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<AddGeneratorEventArgs>? OnAddGenerator;
|
public event EventHandler<AddGeneratorEventArgs>? OnAddGenerator;
|
||||||
|
|
||||||
private PascalType? _simpleExpressionType;
|
|
||||||
|
|
||||||
public PascalType SimpleExpressionType
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_simpleExpressionType is null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _simpleExpressionType;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_simpleExpressionType = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SimpleExpression Create(List<SyntaxNodeBase> children)
|
public static SimpleExpression Create(List<SyntaxNodeBase> children)
|
||||||
{
|
{
|
||||||
return new SimpleExpression { Children = children };
|
return new SimpleExpression { Children = children };
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
using Canon.Core.LexicalParser;
|
using Canon.Core.LexicalParser;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
|
|
||||||
namespace Canon.Core.SyntaxNodes;
|
namespace Canon.Core.SyntaxNodes;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
|
|
||||||
namespace Canon.Core.SyntaxNodes;
|
namespace Canon.Core.SyntaxNodes;
|
||||||
|
@ -8,16 +7,6 @@ public class Subprogram : NonTerminatedSyntaxNode
|
||||||
{
|
{
|
||||||
public override NonTerminatorType Type => NonTerminatorType.Subprogram;
|
public override NonTerminatorType Type => NonTerminatorType.Subprogram;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 子程序头部
|
|
||||||
/// </summary>
|
|
||||||
public SubprogramHead Head => Children[0].Convert<SubprogramHead>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 子程序体
|
|
||||||
/// </summary>
|
|
||||||
public SubprogramBody Body => Children[2].Convert<SubprogramBody>();
|
|
||||||
|
|
||||||
public override void PreVisit(SyntaxNodeVisitor visitor)
|
public override void PreVisit(SyntaxNodeVisitor visitor)
|
||||||
{
|
{
|
||||||
visitor.PreVisit(this);
|
visitor.PreVisit(this);
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
|
|
||||||
namespace Canon.Core.SyntaxNodes;
|
namespace Canon.Core.SyntaxNodes;
|
||||||
|
@ -8,21 +7,6 @@ public class SubprogramBody : NonTerminatedSyntaxNode
|
||||||
{
|
{
|
||||||
public override NonTerminatorType Type => NonTerminatorType.SubprogramBody;
|
public override NonTerminatorType Type => NonTerminatorType.SubprogramBody;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 常量声明部分
|
|
||||||
/// </summary>
|
|
||||||
public ConstDeclarations ConstDeclarations => Children[0].Convert<ConstDeclarations>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 变量声明部分
|
|
||||||
/// </summary>
|
|
||||||
public VarDeclarations VarDeclarations => Children[1].Convert<VarDeclarations>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 语句声明部分
|
|
||||||
/// </summary>
|
|
||||||
public CompoundStatement CompoundStatement => Children[2].Convert<CompoundStatement>();
|
|
||||||
|
|
||||||
public override void PreVisit(SyntaxNodeVisitor visitor)
|
public override void PreVisit(SyntaxNodeVisitor visitor)
|
||||||
{
|
{
|
||||||
visitor.PreVisit(this);
|
visitor.PreVisit(this);
|
||||||
|
|
|
@ -26,8 +26,6 @@ public class SubprogramHead : NonTerminatedSyntaxNode
|
||||||
public IdentifierSemanticToken SubprogramName =>
|
public IdentifierSemanticToken SubprogramName =>
|
||||||
Children[1].Convert<TerminatedSyntaxNode>().Token.Convert<IdentifierSemanticToken>();
|
Children[1].Convert<TerminatedSyntaxNode>().Token.Convert<IdentifierSemanticToken>();
|
||||||
|
|
||||||
public FormalParameter Parameters => Children[2].Convert<FormalParameter>();
|
|
||||||
|
|
||||||
public override void PreVisit(SyntaxNodeVisitor visitor)
|
public override void PreVisit(SyntaxNodeVisitor visitor)
|
||||||
{
|
{
|
||||||
visitor.PreVisit(this);
|
visitor.PreVisit(this);
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
using Canon.Core.LexicalParser;
|
using Canon.Core.LexicalParser;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
using Canon.Core.SemanticParser;
|
|
||||||
|
|
||||||
namespace Canon.Core.SyntaxNodes;
|
namespace Canon.Core.SyntaxNodes;
|
||||||
|
|
||||||
|
@ -45,25 +43,6 @@ public class Term : NonTerminatedSyntaxNode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<MultiplyGeneratorEventArgs>? OnMultiplyGenerator;
|
public event EventHandler<MultiplyGeneratorEventArgs>? OnMultiplyGenerator;
|
||||||
|
|
||||||
private PascalType? _termType;
|
|
||||||
|
|
||||||
public PascalType TermType
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_termType is null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _termType;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_termType = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Term Create(List<SyntaxNodeBase> children)
|
public static Term Create(List<SyntaxNodeBase> children)
|
||||||
{
|
{
|
||||||
return new Term { Children = children };
|
return new Term { Children = children };
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
using Canon.Core.SemanticParser;
|
using Canon.Core.SemanticParser;
|
||||||
|
|
||||||
|
@ -37,11 +36,6 @@ public class TypeSyntaxNode : NonTerminatedSyntaxNode
|
||||||
|
|
||||||
public event EventHandler<ArrayTypeGeneratorEventArgs>? OnArrayTypeGenerator;
|
public event EventHandler<ArrayTypeGeneratorEventArgs>? OnArrayTypeGenerator;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否在过程定义中使用
|
|
||||||
/// </summary>
|
|
||||||
public bool IsProcedure { get; set; }
|
|
||||||
|
|
||||||
private PascalType? _pascalType;
|
private PascalType? _pascalType;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.CodeGenerators;
|
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
|
|
||||||
namespace Canon.Core.SyntaxNodes;
|
namespace Canon.Core.SyntaxNodes;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using Canon.Core.Abstractions;
|
using Canon.Core.Abstractions;
|
||||||
using Canon.Core.Enums;
|
using Canon.Core.Enums;
|
||||||
using Canon.Core.LexicalParser;
|
using Canon.Core.LexicalParser;
|
||||||
using Canon.Core.SemanticParser;
|
|
||||||
|
|
||||||
namespace Canon.Core.SyntaxNodes;
|
namespace Canon.Core.SyntaxNodes;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user