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:
@@ -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);
|
||||
|
@@ -10,6 +10,7 @@ public class BasicType : NonTerminatedSyntaxNode
|
||||
{
|
||||
public override NonTerminatorType Type => NonTerminatorType.BasicType;
|
||||
|
||||
public bool IsProcedure;
|
||||
/// <summary>
|
||||
/// BasicType代表的Pascal类型
|
||||
/// </summary>
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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(" }");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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>
|
||||
|
@@ -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(")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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(" /");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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;}");
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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("; }");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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("}");
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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 };
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -24,9 +24,4 @@ public class VarParameter : NonTerminatedSyntaxNode
|
||||
{
|
||||
return new VarParameter { Children = children };
|
||||
}
|
||||
|
||||
public override void GenerateCCode(CCodeBuilder builder)
|
||||
{
|
||||
ValueParameter.GenerateCCode(builder);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user