feat-generater (#69)

Reviewed-on: PostGuard/Canon#69
Co-authored-by: Lan_G <2911328695@qq.com>
Co-committed-by: Lan_G <2911328695@qq.com>
This commit is contained in:
Lan_G
2024-04-30 14:43:14 +08:00
committed by jackfiled
parent a349f0d9c0
commit 5ca947125b
32 changed files with 1138 additions and 298 deletions

View File

@@ -9,32 +9,13 @@ public class AddOperator : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.AddOperator;
public SemanticToken OperatorToken => Children[0].Convert<TerminatedSyntaxNode>().Token;
public static AddOperator Create(List<SyntaxNodeBase> children)
{
return new AddOperator { Children = children };
}
public override void GenerateCCode(CCodeBuilder builder)
{
var token = Children[0].Convert<TerminatedSyntaxNode>().Token;
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 PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);

View File

@@ -10,6 +10,7 @@ public class BasicType : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.BasicType;
public bool IsProcedure;
/// <summary>
/// BasicType代表的Pascal类型
/// </summary>

View File

@@ -7,6 +7,11 @@ public class CompoundStatement : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.CompoundStatement;
/// <summary>
/// 是否为主函数部分
/// </summary>
public bool IsMain;
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);

View File

@@ -126,24 +126,4 @@ public class ConstValue : NonTerminatedSyntaxNode
{
return new ConstValue { Children = children };
}
public override void GenerateCCode(CCodeBuilder builder)
{
//获取常量值
var token = Children[0].Convert<TerminatedSyntaxNode>().Token;
//constValue -> 'letter'
if (token.TokenType == SemanticTokenType.Character)
{
builder.AddString(" '" + token.LiteralValue + "'");
}
else
{
builder.AddString(" ");
// constValue -> +num | -num | num
foreach (var c in Children)
{
builder.AddString(c.Convert<TerminatedSyntaxNode>().Token.LiteralValue);
}
}
}
}

View File

@@ -22,14 +22,4 @@ public class ElsePart : NonTerminatedSyntaxNode
{
return new ElsePart { Children = children };
}
public override void GenerateCCode(CCodeBuilder builder)
{
if (Children.Count > 0)
{
builder.AddString(" else{");
Children[1].GenerateCCode(builder);
builder.AddString(" }");
}
}
}

View File

@@ -1,6 +1,7 @@
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
using Canon.Core.SemanticParser;
namespace Canon.Core.SyntaxNodes;
@@ -35,6 +36,43 @@ public class Expression : NonTerminatedSyntaxNode
RaiseEvent();
}
public bool IsParam; //是否为传参
public bool ReferenceParam; //是否为引用传参
public bool LastParam; //是否为传参列表里最后一个参数
/// <summary>
/// 是否为数组下标
/// </summary>
public bool IsIndex { get; set; }
/// <summary>
/// 当前表达式对应的数组下标维度的左边界
/// </summary>
public int LeftBound;
public bool IsForConditionBegin { get; set; }
public bool IsForConditionEnd { get; set; }
public bool IsAssign { get; set; }
private IdentifierSemanticToken? _iterator;
public IdentifierSemanticToken Iterator
{
get
{
if (_iterator is null)
{
throw new InvalidOperationException();
}
return _iterator;
}
set
{
_iterator = value;
}
}
/// <summary>
/// 直接赋值产生式的事件
/// </summary>
@@ -91,12 +129,4 @@ public class Expression : NonTerminatedSyntaxNode
OnSimpleExpressionGenerator = null;
OnRelationGenerator = null;
}
public override void GenerateCCode(CCodeBuilder builder)
{
foreach (var child in Children)
{
child.GenerateCCode(builder);
}
}
}

View File

@@ -1,5 +1,6 @@
using Canon.Core.Abstractions;
using Canon.Core.Enums;
using Canon.Core.SemanticParser;
namespace Canon.Core.SyntaxNodes;
@@ -17,6 +18,23 @@ public class ExpressionList : NonTerminatedSyntaxNode
/// </summary>
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>
/// 当前ExpressionList中的Expression定义
/// </summary>

View File

@@ -167,57 +167,4 @@ public class Factor : NonTerminatedSyntaxNode
OnNotGenerator = null;
OnUminusGenerator = null;
}
public override void GenerateCCode(CCodeBuilder builder)
{
if (Children.Count == 1)
{
//factor -> num
if (Children[0].IsTerminated)
{
var token = Children[0].Convert<TerminatedSyntaxNode>().Token;
if (token.TokenType == SemanticTokenType.Number)
{
builder.AddString(" " + token.LiteralValue);
}
}
// factor -> variable
else
{
Children[0].GenerateCCode(builder);
}
}
//factor -> ( expression )
else if (Children.Count == 3)
{
builder.AddString(" (");
Children[1].GenerateCCode(builder);
builder.AddString(")");
}
//factor -> id ( expression )
else if (Children.Count == 4)
{
builder.AddString(" " + Children[0].Convert<TerminatedSyntaxNode>().Token.Convert<IdentifierSemanticToken>()
.IdentifierName);
builder.AddString("(");
Children[2].GenerateCCode(builder);
builder.AddString(")");
}
else
{
//factor -> not factor
builder.AddString(" (");
if (Children[0].Convert<TerminatedSyntaxNode>().Token.TokenType == SemanticTokenType.Keyword)
{
builder.AddString("!");
}
else
{
builder.AddString("-");
}
Children[1].GenerateCCode(builder);
builder.AddString(")");
}
}
}

View File

@@ -1,5 +1,6 @@
using Canon.Core.Abstractions;
using Canon.Core.Enums;
using Canon.Core.SemanticParser;
namespace Canon.Core.SyntaxNodes;
@@ -17,6 +18,11 @@ public class IdentifierVarPart : NonTerminatedSyntaxNode
/// </summary>
public int IndexCount { get; set; }
/// <summary>
/// 数组左边界列表
/// </summary>
public List<int> LeftBounds = new();
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);

View File

@@ -9,6 +9,8 @@ public class MultiplyOperator : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.MultiplyOperator;
public SemanticToken OperatorToken => Children[0].Convert<TerminatedSyntaxNode>().Token;
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
@@ -23,38 +25,4 @@ public class MultiplyOperator : NonTerminatedSyntaxNode
{
return new MultiplyOperator { Children = children };
}
public override void GenerateCCode(CCodeBuilder builder)
{
var token = Children[0].Convert<TerminatedSyntaxNode>().Token;
if (token.TokenType == SemanticTokenType.Operator)
{
var operatorType = token.Convert<OperatorSemanticToken>().OperatorType;
if (operatorType == OperatorType.Multiply)
{
builder.AddString(" *");
}
else if (operatorType == OperatorType.Divide)
{
//实数除法需要将操作数强转为double
builder.AddString(" /(double)");
}
}
else
{
var keywordType = token.Convert<KeywordSemanticToken>().KeywordType;
if (keywordType == KeywordType.And)
{
builder.AddString(" &&");
}
else if (keywordType == KeywordType.Mod)
{
builder.AddString(" %");
}
else
{
builder.AddString(" /");
}
}
}
}

View File

@@ -42,17 +42,4 @@ public class ProgramBody : NonTerminatedSyntaxNode
{
return new ProgramBody { Children = children };
}
public override void GenerateCCode(CCodeBuilder builder)
{
//全局常量,变量
ConstDeclarations.GenerateCCode(builder);
VarDeclarations.GenerateCCode(builder);
//子函数声明
SubprogramDeclarations.GenerateCCode(builder);
//main函数
builder.AddString(" int main(){");
CompoundStatement.GenerateCCode(builder);
builder.AddString(" return 0;}");
}
}

View File

@@ -32,10 +32,4 @@ public class ProgramStruct : NonTerminatedSyntaxNode
{
return new ProgramStruct { Children = children };
}
public override void GenerateCCode(CCodeBuilder builder)
{
builder.AddString("#include <stdbool.h>");
Body.GenerateCCode(builder);
}
}

View File

@@ -9,6 +9,8 @@ public class RelationOperator : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.RelationOperator;
public SemanticToken OperatorToken => Children[0].Convert<TerminatedSyntaxNode>().Token;
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
@@ -23,31 +25,4 @@ public class RelationOperator : NonTerminatedSyntaxNode
{
return new RelationOperator { Children = children };
}
public override void GenerateCCode(CCodeBuilder builder)
{
var operatorType = Children[0].Convert<TerminatedSyntaxNode>().Token.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;
}
}
}

View File

@@ -91,12 +91,4 @@ public class SimpleExpression : NonTerminatedSyntaxNode
OnTermGenerator = null;
OnAddGenerator = null;
}
public override void GenerateCCode(CCodeBuilder builder)
{
foreach (var child in Children)
{
child.GenerateCCode(builder);
}
}
}

View File

@@ -121,48 +121,4 @@ public class Statement : NonTerminatedSyntaxNode
});
}
}
public override void GenerateCCode(CCodeBuilder builder)
{
if (Children.Count == 0)
{
return;
}
// statement -> procedureCall | compoundStatement
if (Children.Count == 1)
{
Children[0].GenerateCCode(builder);
}
//statement -> variable assign expression
else if (Children.Count == 3)
{
Children[0].GenerateCCode(builder);
builder.AddString(" =");
Children[2].GenerateCCode(builder);
}
//if expression then statement else_part
else if (Children.Count == 5)
{
builder.AddString(" if(");
Children[1].GenerateCCode(builder);
builder.AddString("){");
Children[3].GenerateCCode(builder);
builder.AddString("; }");
Children[4].GenerateCCode(builder);
}
//for id assign expression to expression do statement
else
{
string idName = Children[1].Convert<TerminatedSyntaxNode>().Token.Convert<IdentifierSemanticToken>()
.IdentifierName;
builder.AddString(" for(" + idName + " =");
Children[3].GenerateCCode(builder);
builder.AddString("; " + idName + " <=");
Children[5].GenerateCCode(builder);
builder.AddString("; " + idName + "++){");
Children[7].GenerateCCode(builder);
builder.AddString("; }");
}
}
}

View File

@@ -32,14 +32,4 @@ public class Subprogram : NonTerminatedSyntaxNode
{
return new Subprogram { Children = children };
}
public override void GenerateCCode(CCodeBuilder builder)
{
//子函数头
Head.GenerateCCode(builder);
//子函数体
builder.AddString("{");
Body.GenerateCCode(builder);
builder.AddString("}");
}
}

View File

@@ -37,11 +37,4 @@ public class SubprogramBody : NonTerminatedSyntaxNode
{
return new SubprogramBody() { Children = children };
}
public override void GenerateCCode(CCodeBuilder builder)
{
ConstDeclarations.GenerateCCode(builder);
VarDeclarations.GenerateCCode(builder);
CompoundStatement.GenerateCCode(builder);
}
}

View File

@@ -1,5 +1,4 @@
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
namespace Canon.Core.SyntaxNodes;
@@ -22,4 +21,5 @@ public class SubprogramDeclarations : NonTerminatedSyntaxNode
{
return new SubprogramDeclarations { Children = children };
}
}

View File

@@ -91,12 +91,4 @@ public class Term : NonTerminatedSyntaxNode
OnFactorGenerator = null;
OnMultiplyGenerator = null;
}
public override void GenerateCCode(CCodeBuilder builder)
{
foreach (var child in Children)
{
child.GenerateCCode(builder);
}
}
}

View File

@@ -37,6 +37,11 @@ public class TypeSyntaxNode : NonTerminatedSyntaxNode
public event EventHandler<OnArrayTypeGeneratorEventArgs>? OnArrayTypeGenerator;
/// <summary>
/// 是否在过程定义中使用
/// </summary>
public bool IsProcedure { get; set; }
private PascalType? _pascalType;
/// <summary>
@@ -86,17 +91,4 @@ public class TypeSyntaxNode : NonTerminatedSyntaxNode
OnBasicTypeGenerator = null;
OnArrayTypeGenerator = null;
}
public override void GenerateCCode(CCodeBuilder builder)
{
//type -> basic_type
if (Children.Count == 1)
{
Children[0].GenerateCCode(builder);
}
//type -> array [ period ]of basic_type
else
{
}
}
}

View File

@@ -24,9 +24,4 @@ public class VarParameter : NonTerminatedSyntaxNode
{
return new VarParameter { Children = children };
}
public override void GenerateCCode(CCodeBuilder builder)
{
ValueParameter.GenerateCCode(builder);
}
}