feat: 语法树的访问者和类型检测访问者 (#56)

Reviewed-on: PostGuard/Canon#56
This commit is contained in:
2024-04-26 10:18:49 +08:00
parent b20c3234c5
commit 17dbcccb59
63 changed files with 2757 additions and 704 deletions

View File

@@ -1,4 +1,5 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
@@ -33,4 +34,14 @@ public class AddOperator : NonTerminatedSyntaxNode
builder.AddString(" ||");
}
}
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
}

View File

@@ -1,4 +1,5 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
using Canon.Core.SemanticParser;
@@ -9,9 +10,31 @@ public class BasicType : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.BasicType;
public static BasicType Create(List<SyntaxNodeBase> children)
/// <summary>
/// BasicType代表的Pascal类型
/// </summary>
/// <exception cref="InvalidOperationException"></exception>
public PascalType PascalType
{
return new BasicType { Children = children };
get
{
KeywordType keywordType = Children[0].Convert<TerminatedSyntaxNode>().Token
.Convert<KeywordSemanticToken>().KeywordType;
switch (keywordType)
{
case KeywordType.Integer:
return PascalBasicType.Integer;
case KeywordType.Real:
return PascalBasicType.Real;
case KeywordType.Character:
return PascalBasicType.Character;
case KeywordType.Boolean:
return PascalBasicType.Boolean;
}
throw new InvalidOperationException();
}
}
public override void GenerateCCode(CCodeBuilder builder)
@@ -36,27 +59,18 @@ public class BasicType : NonTerminatedSyntaxNode
}
}
/// <summary>
///尝试获取Pascal的基本类型
/// </summary>
/// <returns></returns>
public PascalType TryGetPascalType()
public override void PreVisit(SyntaxNodeVisitor visitor)
{
var keywordType = Children[0].Convert<TerminatedSyntaxNode>().Token
.Convert<KeywordSemanticToken>().KeywordType;
visitor.PreVisit(this);
}
switch (keywordType)
{
case KeywordType.Integer:
return PascalBasicType.Integer;
case KeywordType.Real:
return PascalBasicType.Real;
case KeywordType.Boolean:
return PascalBasicType.Boolean;
case KeywordType.Character:
return PascalBasicType.Character;
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
return PascalBasicType.Void;
public static BasicType Create(List<SyntaxNodeBase> children)
{
return new BasicType { Children = children };
}
}

View File

@@ -1,4 +1,5 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
namespace Canon.Core.SyntaxNodes;
@@ -9,6 +10,16 @@ public class CompoundStatement : NonTerminatedSyntaxNode
public IEnumerable<Statement> Statements => Children[1].Convert<StatementList>().Statements;
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static CompoundStatement Create(List<SyntaxNodeBase> children)
{
return new CompoundStatement { Children = children };

View File

@@ -1,4 +1,5 @@
using Canon.Core.Enums;
using Canon.Core.Abstractions;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
namespace Canon.Core.SyntaxNodes;
@@ -17,6 +18,16 @@ public class ConstDeclaration : NonTerminatedSyntaxNode
/// </summary>
public (IdentifierSemanticToken, ConstValue) ConstValue => GetConstValue();
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static ConstDeclaration Create(List<SyntaxNodeBase> children)
{
bool isRecursive;

View File

@@ -1,4 +1,5 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
@@ -13,6 +14,16 @@ public class ConstDeclarations : NonTerminatedSyntaxNode
/// </summary>
public IEnumerable<(IdentifierSemanticToken, ConstValue)> ConstValues => GetConstValues();
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static ConstDeclarations Create(List<SyntaxNodeBase> children)
{
return new ConstDeclarations { Children = children };

View File

@@ -1,12 +1,127 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
using Canon.Core.SemanticParser;
namespace Canon.Core.SyntaxNodes;
/// <summary>
/// 使用数值产生式事件的事件参数
/// </summary>
public class NumberConstValueEventArgs : EventArgs
{
/// <summary>
/// 是否含有负号
/// </summary>
public bool IsNegative { get; init; }
/// <summary>
/// 数值记号
/// </summary>
public required NumberSemanticToken Token { get; init; }
}
/// <summary>
/// 使用字符产生式事件的事件参数
/// </summary>
public class CharacterConstValueEventArgs : EventArgs
{
/// <summary>
/// 字符记号
/// </summary>
public required CharacterSemanticToken Token { get; init; }
}
public class ConstValue : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.ConstValue;
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
RaiseGeneratorEvent();
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
RaiseGeneratorEvent();
}
private PascalType? _constType;
/// <summary>
/// 该ConstValue代表的类型
/// </summary>
/// <exception cref="InvalidOperationException">尚未分析该类型</exception>
public PascalType ConstType
{
get
{
if (_constType is null)
{
throw new InvalidOperationException("ConstType has not been set");
}
return _constType;
}
set
{
_constType = value;
}
}
/// <summary>
/// 使用数值产生式的事件
/// </summary>
public event EventHandler<NumberConstValueEventArgs>? OnNumberGenerator;
/// <summary>
/// 使用字符产生式的事件
/// </summary>
public event EventHandler<CharacterConstValueEventArgs>? OnCharacterGenerator;
private void RaiseGeneratorEvent()
{
if (Children.Count == 2)
{
OperatorSemanticToken operatorSemanticToken = Children[0].Convert<TerminatedSyntaxNode>().Token
.Convert<OperatorSemanticToken>();
NumberSemanticToken numberSemanticToken = Children[1].Convert<TerminatedSyntaxNode>().Token
.Convert<NumberSemanticToken>();
OnNumberGenerator?.Invoke(this, new NumberConstValueEventArgs
{
Token = numberSemanticToken,
IsNegative = operatorSemanticToken.OperatorType == OperatorType.Minus
});
return;
}
SemanticToken token = Children[0].Convert<TerminatedSyntaxNode>().Token;
if (token.TokenType == SemanticTokenType.Number)
{
OnNumberGenerator?.Invoke(this,
new NumberConstValueEventArgs
{
Token = token.Convert<NumberSemanticToken>()
});
}
else
{
OnCharacterGenerator?.Invoke(this, new CharacterConstValueEventArgs
{
Token = token.Convert<CharacterSemanticToken>()
});
}
OnNumberGenerator = null;
OnCharacterGenerator = null;
}
public static ConstValue Create(List<SyntaxNodeBase> children)
{
return new ConstValue { Children = children };

View File

@@ -1,4 +1,5 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
namespace Canon.Core.SyntaxNodes;
@@ -7,6 +8,16 @@ public class ElsePart : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.ElsePart;
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static ElsePart Create(List<SyntaxNodeBase> children)
{
return new ElsePart { Children = children };

View File

@@ -1,17 +1,97 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
using Canon.Core.SemanticParser;
namespace Canon.Core.SyntaxNodes;
public class OnSimpleExpressionGeneratorEventArgs : EventArgs
{
public required SimpleExpression SimpleExpression { get; init; }
}
public class OnRelationGeneratorEventArgs : EventArgs
{
public required SimpleExpression Left { get; init; }
public required RelationOperator Operator { get; init; }
public required SimpleExpression Right { get; init; }
}
public class Expression : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.Expression;
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
RaiseEvent();
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
RaiseEvent();
}
/// <summary>
/// 直接赋值产生式的事件
/// </summary>
public event EventHandler<OnSimpleExpressionGeneratorEventArgs>? OnSimpleExpressionGenerator;
/// <summary>
/// 关系产生式的事件
/// </summary>
public event EventHandler<OnRelationGeneratorEventArgs>? OnRelationGenerator;
private PascalType? _expressionType;
public PascalType ExprssionType
{
get
{
if (_expressionType is null)
{
throw new InvalidOperationException();
}
return _expressionType;
}
set
{
_expressionType = value;
}
}
public static Expression Create(List<SyntaxNodeBase> children)
{
return new Expression { Children = children };
}
private void RaiseEvent()
{
if (Children.Count == 1)
{
OnSimpleExpressionGenerator?.Invoke(this, new OnSimpleExpressionGeneratorEventArgs
{
SimpleExpression = Children[0].Convert<SimpleExpression>()
});
}
else
{
OnRelationGenerator?.Invoke(this, new OnRelationGeneratorEventArgs
{
Left = Children[0].Convert<SimpleExpression>(),
Operator = Children[1].Convert<RelationOperator>(),
Right = Children[2].Convert<SimpleExpression>()
});
}
OnSimpleExpressionGenerator = null;
OnRelationGenerator = null;
}
public override void GenerateCCode(CCodeBuilder builder)
{
foreach (var child in Children)

View File

@@ -1,4 +1,4 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.Enums;
namespace Canon.Core.SyntaxNodes;
@@ -7,67 +7,39 @@ public class ExpressionList : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.ExpressionList;
public bool IsRecursive { get; private init; }
/// <summary>
/// 声明的表达式列表
/// 表达式列表
/// </summary>
public IEnumerable<Expression> Expressions => GetExpressions();
public List<Expression> Expressions { get; } = [];
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static ExpressionList Create(List<SyntaxNodeBase> children)
{
bool isRecursive;
ExpressionList result = new() { Children = children };
if (children.Count == 1)
{
isRecursive = false;
result.Expressions.Add(children[0].Convert<Expression>());
}
else if (children.Count == 3)
{
isRecursive = true;
}
else
{
throw new InvalidOperationException();
}
return new ExpressionList { Children = children, IsRecursive = isRecursive };
}
private IEnumerable<Expression> GetExpressions()
{
ExpressionList list = this;
while (true)
{
if (list.IsRecursive)
foreach (Expression expression in children[0].Convert<ExpressionList>().Expressions)
{
yield return list.Children[2].Convert<Expression>();
list = list.Children[0].Convert<ExpressionList>();
result.Expressions.Add(expression);
}
else
{
yield return list.Children[0].Convert<Expression>();
break;
}
}
}
public override void GenerateCCode(CCodeBuilder builder)
{
//用逗号分隔输出的expression
using var enumerator = Expressions.GetEnumerator();
if (enumerator.MoveNext())
{
enumerator.Current.GenerateCCode(builder);
}
while (enumerator.MoveNext())
{
builder.AddString(", ");
enumerator.Current.GenerateCCode(builder);
result.Expressions.Add(children[2].Convert<Expression>());
}
return result;
}
}

View File

@@ -1,18 +1,173 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
using Canon.Core.SemanticParser;
namespace Canon.Core.SyntaxNodes;
public class OnNumberGeneratorEventArgs : EventArgs
{
public required NumberSemanticToken Token { get; init; }
}
public class OnVariableGeneratorEventArgs : EventArgs
{
public required Variable Variable { get; init; }
}
public class OnParethnesisGeneratorEventArgs : EventArgs
{
public required Expression Expression { get; init; }
}
public class OnProcedureCallGeneratorEventArgs : EventArgs
{
public required IdentifierSemanticToken ProcedureName { get; init; }
public required ExpressionList Parameters { get; init; }
}
public class OnNotGeneratorEventArgs : EventArgs
{
public required Factor Factor { get; init; }
}
public class OnUminusGeneratorEventArgs : EventArgs
{
public required Factor Factor { get; init; }
}
public class Factor : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.Factor;
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
RaiseEvent();
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
RaiseEvent();
}
/// <summary>
/// 使用数值产生式的事件
/// </summary>
public event EventHandler<OnNumberGeneratorEventArgs>? OnNumberGenerator;
/// <summary>
/// 使用括号产生式的事件
/// </summary>
public event EventHandler<OnParethnesisGeneratorEventArgs>? OnParethnesisGenerator;
/// <summary>
/// 使用变量产生式的事件
/// </summary>
public event EventHandler<OnVariableGeneratorEventArgs>? OnVariableGenerator;
/// <summary>
/// 使用过程调用产生式的事件
/// </summary>
public event EventHandler<OnProcedureCallGeneratorEventArgs>? OnProcedureCallGenerator;
/// <summary>
/// 使用否定产生式的事件
/// </summary>
public event EventHandler<OnNotGeneratorEventArgs>? OnNotGenerator;
/// <summary>
/// 使用负号产生式的事件
/// </summary>
public event EventHandler<OnUminusGeneratorEventArgs>? OnUminusGenerator;
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)
{
return new Factor { Children = children };
}
private void RaiseEvent()
{
if (Children.Count == 1)
{
//factor -> num
if (Children[0].IsTerminated)
{
SemanticToken token = Children[0].Convert<TerminatedSyntaxNode>().Token;
OnNumberGenerator?.Invoke(this,
new OnNumberGeneratorEventArgs { Token = token.Convert<NumberSemanticToken>() });
}
// factor -> variable
else
{
OnVariableGenerator?.Invoke(this,
new OnVariableGeneratorEventArgs { Variable = Children[0].Convert<Variable>() });
}
}
//factor -> ( expression )
else if (Children.Count == 3)
{
OnParethnesisGenerator?.Invoke(this,
new OnParethnesisGeneratorEventArgs { Expression = Children[1].Convert<Expression>() });
}
//factor -> id ( expression )
else if (Children.Count == 4)
{
OnProcedureCallGenerator?.Invoke(this,
new OnProcedureCallGeneratorEventArgs
{
ProcedureName =
Children[0].Convert<TerminatedSyntaxNode>().Token.Convert<IdentifierSemanticToken>(),
Parameters = Children[2].Convert<ExpressionList>()
});
}
else
{
SemanticToken token = Children[0].Convert<TerminatedSyntaxNode>().Token;
Factor factor = Children[1].Convert<Factor>();
if (token.TokenType == SemanticTokenType.Keyword)
{
// factor -> not factor
OnNotGenerator?.Invoke(this, new OnNotGeneratorEventArgs { Factor = factor });
}
else
{
// factor -> uminus factor
OnUminusGenerator?.Invoke(this, new OnUminusGeneratorEventArgs { Factor = factor });
}
}
OnNumberGenerator = null;
OnVariableGenerator = null;
OnParethnesisGenerator = null;
OnProcedureCallGenerator = null;
OnNotGenerator = null;
OnUminusGenerator = null;
}
public override void GenerateCCode(CCodeBuilder builder)
{
if (Children.Count == 1)
@@ -42,14 +197,15 @@ public class Factor : NonTerminatedSyntaxNode
//factor -> id ( expression )
else if (Children.Count == 4)
{
builder.AddString(" " + Children[0].Convert<TerminatedSyntaxNode>().Token.
Convert<IdentifierSemanticToken>().IdentifierName);
builder.AddString(" " + Children[0].Convert<TerminatedSyntaxNode>().Token.Convert<IdentifierSemanticToken>()
.IdentifierName);
builder.AddString("(");
Children[2].GenerateCCode(builder);
builder.AddString(")");
}
else
{ //factor -> not factor
{
//factor -> not factor
builder.AddString(" (");
if (Children[0].Convert<TerminatedSyntaxNode>().Token.TokenType == SemanticTokenType.Keyword)
{

View File

@@ -1,4 +1,5 @@
using Canon.Core.Enums;
using Canon.Core.Abstractions;
using Canon.Core.Enums;
namespace Canon.Core.SyntaxNodes;
@@ -6,26 +7,18 @@ public class FormalParameter : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.FormalParameter;
/// <summary>
/// 声明的参数列表
/// </summary>
public IEnumerable<Parameter> Parameters => GetParameters();
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static FormalParameter Create(List<SyntaxNodeBase> children)
{
return new FormalParameter { Children = children };
}
private IEnumerable<Parameter> GetParameters()
{
if (Children.Count == 0)
{
yield break;
}
foreach (Parameter parameter in Children[1].Convert<ParameterList>().Parameters)
{
yield return parameter;
}
}
}

View File

@@ -1,75 +1,97 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
using Canon.Core.SemanticParser;
namespace Canon.Core.SyntaxNodes;
public class OnIdentifierGeneratorEventArgs : EventArgs
{
public required IdentifierSemanticToken IdentifierToken { get; init; }
public required IdentifierList IdentifierList { get; init; }
}
public class OnTypeGeneratorEventArgs : EventArgs
{
public required TypeSyntaxNode TypeSyntaxNode { get; init; }
}
public class IdentifierList : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.IdentifierList;
/// <summary>
/// 是否含有递归定义
/// </summary>
public bool IsRecursive { get; private init; }
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
RaiseEvent();
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
RaiseEvent();
}
private PascalType? _definitionType;
/// <summary>
/// 声明的标识符列表
/// IdentifierList中定义的类型
/// </summary>
public IEnumerable<IdentifierSemanticToken> Identifiers => GetIdentifiers();
/// <exception cref="InvalidOperationException">尚未确定定义的类型</exception>
public PascalType DefinitionType
{
get
{
if (_definitionType is null)
{
throw new InvalidOperationException();
}
return _definitionType;
}
set
{
_definitionType = value;
}
}
/// <summary>
/// 是否为参数中的引用参数
/// </summary>
public bool IsReference { get; set; }
/// <summary>
/// 是否在过程定义中使用
/// </summary>
public bool IsProcedure { get; set; }
public event EventHandler<OnIdentifierGeneratorEventArgs>? OnIdentifierGenerator;
public event EventHandler<OnTypeGeneratorEventArgs>? OnTypeGenerator;
public static IdentifierList Create(List<SyntaxNodeBase> children)
{
bool isRecursive;
return new IdentifierList { Children = children };
}
if (children.Count == 2)
private void RaiseEvent()
{
if (Children.Count == 2)
{
isRecursive = false;
}
else if (children.Count == 3)
{
isRecursive = true;
OnTypeGenerator?.Invoke(this,
new OnTypeGeneratorEventArgs { TypeSyntaxNode = Children[1].Convert<TypeSyntaxNode>() });
}
else
{
throw new InvalidOperationException();
}
return new IdentifierList { IsRecursive = isRecursive, Children = children };
}
private IEnumerable<IdentifierSemanticToken> GetIdentifiers()
{
IdentifierList identifier = this;
while (true)
{
if (identifier.IsRecursive)
OnIdentifierGenerator?.Invoke(this, new OnIdentifierGeneratorEventArgs
{
yield return (IdentifierSemanticToken)identifier.Children[2].Convert<TerminatedSyntaxNode>().Token;
identifier = identifier.Children[0].Convert<IdentifierList>();
}
else
{
yield return (IdentifierSemanticToken)identifier.Children[0].Convert<TerminatedSyntaxNode>().Token;
break;
}
}
}
public override void GenerateCCode(CCodeBuilder builder)
{
//用逗号分隔输出的expression
using var enumerator = Identifiers.Reverse().GetEnumerator();
if (enumerator.MoveNext())
{
builder.AddString(" " + enumerator.Current.IdentifierName);
IdentifierToken = Children[1].Convert<TerminatedSyntaxNode>().Token.Convert<IdentifierSemanticToken>(),
IdentifierList = Children[2].Convert<IdentifierList>()
});
}
while (enumerator.MoveNext())
{
builder.AddString(", " + enumerator.Current.IdentifierName);
}
OnTypeGenerator = null;
OnIdentifierGenerator = null;
}
}

View File

@@ -1,54 +1,46 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.Enums;
using Canon.Core.SemanticParser;
namespace Canon.Core.SyntaxNodes;
public class OnParameterGeneratorEventArgs : EventArgs
{
public required ExpressionList Parameters { get; init; }
}
public class IdentifierVarPart : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.IdVarPart;
/// <summary>
/// 是否声明了索引部分
/// </summary>
public bool Exist { get; private init; }
/// <summary>
/// 索引中的位置声明
/// </summary>
public IEnumerable<Expression> Positions => GetPositions();
private IEnumerable<Expression> GetPositions()
public override void PreVisit(SyntaxNodeVisitor visitor)
{
if (!Exist)
{
yield break;
}
foreach (Expression expression in Children[1].Convert<ExpressionList>().Expressions)
{
yield return expression;
}
visitor.PreVisit(this);
RaiseEvent();
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
RaiseEvent();
}
public event EventHandler<OnParameterGeneratorEventArgs>? OnParameterGenerator;
public static IdentifierVarPart Create(List<SyntaxNodeBase> children)
{
bool exist;
if (children.Count == 0)
{
exist = false;
}
else if (children.Count == 3)
{
exist = true;
}
else
{
throw new InvalidOperationException();
}
return new IdentifierVarPart { Children = children, Exist = exist };
return new IdentifierVarPart { Children = children };
}
private void RaiseEvent()
{
if (Children.Count == 3)
{
OnParameterGenerator?.Invoke(this, new OnParameterGeneratorEventArgs
{
Parameters = Children[1].Convert<ExpressionList>()
});
}
OnParameterGenerator = null;
}
}

View File

@@ -1,4 +1,5 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
@@ -8,6 +9,16 @@ public class MultiplyOperator : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.MultiplyOperator;
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static MultiplyOperator Create(List<SyntaxNodeBase> children)
{
return new MultiplyOperator { Children = children };
@@ -45,6 +56,5 @@ public class MultiplyOperator : NonTerminatedSyntaxNode
builder.AddString(" /");
}
}
}
}

View File

@@ -1,4 +1,5 @@
using System.Collections;
using Canon.Core.Abstractions;
using Canon.Core.Enums;
namespace Canon.Core.SyntaxNodes;
@@ -9,6 +10,8 @@ public abstract class NonTerminatedSyntaxNode : SyntaxNodeBase, IEnumerable<Synt
public abstract NonTerminatorType Type { get; }
public required List<SyntaxNodeBase> Children { get; init; }
public IEnumerator<SyntaxNodeBase> GetEnumerator()

View File

@@ -1,4 +1,5 @@
using Canon.Core.Enums;
using Canon.Core.Abstractions;
using Canon.Core.Enums;
namespace Canon.Core.SyntaxNodes;
@@ -17,6 +18,16 @@ public class Parameter : NonTerminatedSyntaxNode
public ValueParameter ValueParameter =>
IsVar ? Children[0].Convert<VarParameter>().ValueParameter : Children[0].Convert<ValueParameter>();
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static Parameter Create(List<SyntaxNodeBase> children)
{
NonTerminatedSyntaxNode node = children[0].Convert<NonTerminatedSyntaxNode>();

View File

@@ -1,4 +1,5 @@
using Canon.Core.Enums;
using Canon.Core.Abstractions;
using Canon.Core.Enums;
namespace Canon.Core.SyntaxNodes;
@@ -13,6 +14,16 @@ public class ParameterList : NonTerminatedSyntaxNode
/// </summary>
public IEnumerable<Parameter> Parameters => GetParameters();
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static ParameterList Create(List<SyntaxNodeBase> children)
{
bool isRecursive;

View File

@@ -1,4 +1,4 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
@@ -8,63 +8,61 @@ public class Period : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.Period;
public bool IsRecursive { get; private init; }
/// <summary>
/// 所有定义的Period
/// </summary>
public List<Period> Periods { get; } = [];
/// <summary>
/// 数组上下界列表
/// 数组的开始下标和结束下标
/// </summary>
public IEnumerable<(NumberSemanticToken, NumberSemanticToken)> Ranges => GetRanges();
public static Period Create(List<SyntaxNodeBase> children)
public (NumberSemanticToken, NumberSemanticToken) Range
{
bool isRecursive;
if (children.Count == 3)
get
{
isRecursive = false;
}
else if (children.Count == 5)
{
isRecursive = true;
}
else
{
throw new InvalidOperationException();
}
return new Period { Children = children, IsRecursive = isRecursive };
}
private (NumberSemanticToken, NumberSemanticToken) GetRange()
{
if (IsRecursive)
{
return ((NumberSemanticToken)Children[2].Convert<TerminatedSyntaxNode>().Token,
(NumberSemanticToken)Children[4].Convert<TerminatedSyntaxNode>().Token);
}
else
{
return ((NumberSemanticToken)Children[0].Convert<TerminatedSyntaxNode>().Token,
(NumberSemanticToken)Children[2].Convert<TerminatedSyntaxNode>().Token);
}
}
private IEnumerable<(NumberSemanticToken, NumberSemanticToken)> GetRanges()
{
Period period = this;
while (true)
{
if (period.IsRecursive)
if (Children.Count == 3)
{
yield return period.GetRange();
period = period.Children[0].Convert<Period>();
return (Children[0].Convert<TerminatedSyntaxNode>().Token.Convert<NumberSemanticToken>(),
Children[2].Convert<TerminatedSyntaxNode>().Token.Convert<NumberSemanticToken>());
}
else
{
yield return period.GetRange();
break;
return (Children[2].Convert<TerminatedSyntaxNode>().Token.Convert<NumberSemanticToken>(),
Children[4].Convert<TerminatedSyntaxNode>().Token.Convert<NumberSemanticToken>());
}
}
}
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static Period Create(List<SyntaxNodeBase> children)
{
Period result = new() { Children = children };
if (children.Count == 3)
{
result.Periods.Add(result);
}
else
{
Period child = children[0].Convert<Period>();
foreach (Period period in child.Periods)
{
result.Periods.Add(period);
}
result.Periods.Add(result);
}
return result;
}
}

View File

@@ -1,4 +1,5 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
@@ -13,6 +14,16 @@ public class ProcedureCall : NonTerminatedSyntaxNode
public IEnumerable<Expression> Arguments => GetArguments();
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static ProcedureCall Create(List<SyntaxNodeBase> children)
{
return new ProcedureCall { Children = children };

View File

@@ -1,4 +1,5 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
namespace Canon.Core.SyntaxNodes;
@@ -27,6 +28,16 @@ public class ProgramBody : NonTerminatedSyntaxNode
/// </summary>
public CompoundStatement CompoundStatement => Children[3].Convert<CompoundStatement>();
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static ProgramBody Create(List<SyntaxNodeBase> children)
{
return new ProgramBody { Children = children };

View File

@@ -1,4 +1,5 @@
using Canon.Core.Enums;
using Canon.Core.Abstractions;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
namespace Canon.Core.SyntaxNodes;
@@ -13,28 +14,18 @@ public class ProgramHead : NonTerminatedSyntaxNode
public IdentifierSemanticToken ProgramName
=> (IdentifierSemanticToken)Children[1].Convert<TerminatedSyntaxNode>().Token;
/// <summary>
/// 暂时意义不明的标识符列表
/// https://wiki.freepascal.org/Program_Structure/zh_CN
/// TODO: 查阅资料
/// </summary>
public IEnumerable<IdentifierSemanticToken> FileList => GetFileList();
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static ProgramHead Create(List<SyntaxNodeBase> children)
{
return new ProgramHead { Children = children };
}
private IEnumerable<IdentifierSemanticToken> GetFileList()
{
if (Children.Count == 2)
{
yield break;
}
foreach (IdentifierSemanticToken token in Children[3].Convert<IdentifierList>().Identifiers)
{
yield return token;
}
}
}

View File

@@ -1,4 +1,5 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
namespace Canon.Core.SyntaxNodes;
@@ -17,6 +18,16 @@ public class ProgramStruct : NonTerminatedSyntaxNode
/// </summary>
public ProgramBody Body => Children[2].Convert<ProgramBody>();
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static ProgramStruct Create(List<SyntaxNodeBase> children)
{
return new ProgramStruct { Children = children };

View File

@@ -1,4 +1,5 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
@@ -8,6 +9,16 @@ public class RelationOperator : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.RelationOperator;
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static RelationOperator Create(List<SyntaxNodeBase> children)
{
return new RelationOperator { Children = children };
@@ -15,8 +26,8 @@ public class RelationOperator : NonTerminatedSyntaxNode
public override void GenerateCCode(CCodeBuilder builder)
{
var operatorType = Children[0].Convert<TerminatedSyntaxNode>().Token.
Convert<OperatorSemanticToken>().OperatorType;
var operatorType = Children[0].Convert<TerminatedSyntaxNode>().Token.Convert<OperatorSemanticToken>()
.OperatorType;
switch (operatorType)
{
case OperatorType.Equal:

View File

@@ -1,17 +1,97 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
using Canon.Core.SemanticParser;
namespace Canon.Core.SyntaxNodes;
public class OnTermGeneratorEventArgs : EventArgs
{
public required Term Term { get; init; }
}
public class OnAddGeneratorEventArgs : EventArgs
{
public required SimpleExpression Left { get; init; }
public required AddOperator Operator { get; init; }
public required Term Right { get; init; }
}
public class SimpleExpression : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.SimpleExpression;
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
RaiseEvent();
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
RaiseEvent();
}
/// <summary>
/// 直接赋值产生式的事件
/// </summary>
public event EventHandler<OnTermGeneratorEventArgs>? OnTermGenerator;
/// <summary>
/// 加法产生式的事件
/// </summary>
public event EventHandler<OnAddGeneratorEventArgs>? 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)
{
return new SimpleExpression { Children = children };
}
private void RaiseEvent()
{
if (Children.Count == 1)
{
OnTermGenerator?.Invoke(this, new OnTermGeneratorEventArgs
{
Term = Children[0].Convert<Term>()
});
}
else
{
OnAddGenerator?.Invoke(this, new OnAddGeneratorEventArgs
{
Left = Children[0].Convert<SimpleExpression>(),
Operator = Children[1].Convert<AddOperator>(),
Right = Children[2].Convert<Term>()
});
}
OnTermGenerator = null;
OnAddGenerator = null;
}
public override void GenerateCCode(CCodeBuilder builder)
{
foreach (var child in Children)

View File

@@ -1,24 +1,134 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
namespace Canon.Core.SyntaxNodes;
public class OnAssignGeneratorEventArgs : EventArgs
{
public required Variable Variable { get; init; }
public required Expression Expression { get; init; }
}
public class OnReturnGeneratorEventArgs : EventArgs
{
public required IdentifierSemanticToken FunctionName { get; set; }
public required Expression Expression { get; init; }
}
public class OnIfGeneratorEventArgs : EventArgs
{
public required Expression Condition { get; init; }
public required Statement Sentence { get; init; }
public required ElsePart ElseSentence { get; init; }
}
public class OnForGeneratorEventArgs : EventArgs
{
public required IdentifierSemanticToken Iterator { get; init; }
public required Expression Begin { get; init; }
public required Expression End { get; init; }
public required Statement Sentence { get; init; }
}
public class Statement : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.Statement;
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
RaiseEvent();
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
RaiseEvent();
}
/// <summary>
/// 使用赋值产生式的事件
/// </summary>
public event EventHandler<OnAssignGeneratorEventArgs>? OnAssignGenerator;
/// <summary>
/// 使用返回产生式的事件
/// </summary>
public event EventHandler<OnReturnGeneratorEventArgs>? OnReturnGenerator;
/// <summary>
/// 使用If产生式的事件
/// </summary>
public event EventHandler<OnIfGeneratorEventArgs>? OnIfGenerator;
/// <summary>
/// 使用For产生式的事件
/// </summary>
public event EventHandler<OnForGeneratorEventArgs>? OnForGenerator;
public static Statement Create(List<SyntaxNodeBase> children)
{
return new Statement { Children = children };
}
private void RaiseEvent()
{
if (Children.Count == 2)
{
if (Children[0].IsTerminated)
{
OnReturnGenerator?.Invoke(this, new OnReturnGeneratorEventArgs
{
FunctionName = Children[0].Convert<TerminatedSyntaxNode>().Token.Convert<IdentifierSemanticToken>(),
Expression = Children[2].Convert<Expression>()
});
}
else
{
OnAssignGenerator?.Invoke(this, new OnAssignGeneratorEventArgs
{
Variable = Children[0].Convert<Variable>(),
Expression = Children[2].Convert<Expression>()
});
}
}
else if (Children.Count == 5)
{
OnIfGenerator?.Invoke(this, new OnIfGeneratorEventArgs
{
Condition = Children[1].Convert<Expression>(),
Sentence = Children[3].Convert<Statement>(),
ElseSentence = Children[4].Convert<ElsePart>()
});
}
else if (Children.Count == 8)
{
OnForGenerator?.Invoke(this, new OnForGeneratorEventArgs
{
Iterator = Children[1].Convert<TerminatedSyntaxNode>().Token.Convert<IdentifierSemanticToken>(),
Begin = Children[3].Convert<Expression>(),
End = Children[5].Convert<Expression>(),
Sentence = Children[7].Convert<Statement>()
});
}
}
public override void GenerateCCode(CCodeBuilder builder)
{
if (Children.Count == 0)
{
return;
}
// statement -> procedureCall | compoundStatement
if (Children.Count == 1)
{

View File

@@ -1,4 +1,5 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
namespace Canon.Core.SyntaxNodes;
@@ -11,6 +12,16 @@ public class StatementList : NonTerminatedSyntaxNode
public IEnumerable<Statement> Statements => GetStatements();
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static StatementList Create(List<SyntaxNodeBase> children)
{
bool isRecursive;

View File

@@ -1,4 +1,5 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
namespace Canon.Core.SyntaxNodes;
@@ -17,6 +18,16 @@ public class Subprogram : NonTerminatedSyntaxNode
/// </summary>
public SubprogramBody Body => Children[2].Convert<SubprogramBody>();
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static Subprogram Create(List<SyntaxNodeBase> children)
{
return new Subprogram { Children = children };

View File

@@ -1,4 +1,5 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
namespace Canon.Core.SyntaxNodes;
@@ -22,6 +23,16 @@ public class SubprogramBody : NonTerminatedSyntaxNode
/// </summary>
public CompoundStatement CompoundStatement => Children[2].Convert<CompoundStatement>();
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static SubprogramBody Create(List<SyntaxNodeBase> children)
{
return new SubprogramBody() { Children = children };

View File

@@ -1,4 +1,5 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
namespace Canon.Core.SyntaxNodes;
@@ -12,6 +13,16 @@ public class SubprogramDeclarations : NonTerminatedSyntaxNode
/// </summary>
public IEnumerable<Subprogram> Subprograms => GetSubprograms();
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static SubprogramDeclarations Create(List<SyntaxNodeBase> children)
{
return new SubprogramDeclarations { Children = children };

View File

@@ -1,25 +1,48 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
namespace Canon.Core.SyntaxNodes;
public class OnProcedureGeneratorEventArgs : EventArgs;
public class OnFunctionGeneratorEventArgs : EventArgs
{
public required BasicType ReturnType { get; init; }
}
public class SubprogramHead : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.SubprogramHead;
/// <summary>
/// 过程定义还是函数定义
/// </summary>
public bool IsProcedure { get; private init; }
/// <summary>
/// 子程序的名称
/// </summary>
public IdentifierSemanticToken SubprogramName =>
(IdentifierSemanticToken)Children[1].Convert<TerminatedSyntaxNode>().Token;
Children[1].Convert<TerminatedSyntaxNode>().Token.Convert<IdentifierSemanticToken>();
/// <summary>
/// 子程序的参数
/// </summary>
public IEnumerable<Parameter> Parameters => Children[2].Convert<FormalParameter>().Parameters;
public FormalParameter Parameters => Children[2].Convert<FormalParameter>();
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
RaiseEvent();
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
RaiseEvent();
}
public event EventHandler<OnProcedureGeneratorEventArgs>? OnProcedureGenerator;
public event EventHandler<OnFunctionGeneratorEventArgs>? OnFunctionGenerator;
public static SubprogramHead Create(List<SyntaxNodeBase> children)
{
@@ -44,27 +67,19 @@ public class SubprogramHead : NonTerminatedSyntaxNode
return new SubprogramHead { Children = children, IsProcedure = isProcedure };
}
public override void GenerateCCode(CCodeBuilder builder)
private void RaiseEvent()
{
//可能要用到符号表
if (IsProcedure)
{
builder.AddString("void ");
OnProcedureGenerator?.Invoke(this, new OnProcedureGeneratorEventArgs());
}
else
{
//返回类型暂时未知
builder.AddString("int ");
OnFunctionGenerator?.Invoke(this,
new OnFunctionGeneratorEventArgs { ReturnType = Children[4].Convert<BasicType>() });
}
builder.AddString(SubprogramName.LiteralValue);
builder.AddString("(");
foreach (var param in Parameters)
{
}
builder.AddString(")");
OnProcedureGenerator = null;
OnFunctionGenerator = null;
}
}

View File

@@ -9,6 +9,10 @@ public abstract class SyntaxNodeBase : ICCodeGenerator
{
public abstract bool IsTerminated { get; }
public abstract void PreVisit(SyntaxNodeVisitor visitor);
public abstract void PostVisit(SyntaxNodeVisitor visitor);
public T Convert<T>() where T : SyntaxNodeBase
{
T? result = this as T;
@@ -26,7 +30,6 @@ public abstract class SyntaxNodeBase : ICCodeGenerator
/// </summary>
public virtual void GenerateCCode(CCodeBuilder builder)
{
}
public override string ToString()

View File

@@ -1,17 +1,97 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
using Canon.Core.SemanticParser;
namespace Canon.Core.SyntaxNodes;
public class OnFactorGeneratorEventArgs : EventArgs
{
public required Factor Factor { get; init; }
}
public class OnMultiplyGeneratorEventArgs : EventArgs
{
public required Term Left { get; init; }
public required MultiplyOperator Operator { get; init; }
public required Factor Right { get; init; }
}
public class Term : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.Term;
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
RaiseEvent();
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
RaiseEvent();
}
/// <summary>
/// 直接赋值产生式的事件
/// </summary>
public event EventHandler<OnFactorGeneratorEventArgs>? OnFactorGenerator;
/// <summary>
/// 乘法产生式的事件
/// </summary>
public event EventHandler<OnMultiplyGeneratorEventArgs>? 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)
{
return new Term { Children = children };
}
private void RaiseEvent()
{
if (Children.Count == 1)
{
OnFactorGenerator?.Invoke(this, new OnFactorGeneratorEventArgs
{
Factor = Children[0].Convert<Factor>()
});
}
else
{
OnMultiplyGenerator?.Invoke(this, new OnMultiplyGeneratorEventArgs
{
Left = Children[0].Convert<Term>(),
Operator = Children[1].Convert<MultiplyOperator>(),
Right = Children[2].Convert<Factor>()
});
}
OnFactorGenerator = null;
OnMultiplyGenerator = null;
}
public override void GenerateCCode(CCodeBuilder builder)
{
foreach (var child in Children)

View File

@@ -1,4 +1,5 @@
using Canon.Core.LexicalParser;
using Canon.Core.Abstractions;
using Canon.Core.LexicalParser;
namespace Canon.Core.SyntaxNodes;
@@ -6,6 +7,16 @@ public class TerminatedSyntaxNode : SyntaxNodeBase
{
public override bool IsTerminated => true;
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public required SemanticToken Token { get; init; }
public override string ToString()

View File

@@ -1,17 +1,92 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
using Canon.Core.SemanticParser;
namespace Canon.Core.SyntaxNodes;
public class OnBasicTypeGeneratorEventArgs : EventArgs
{
public required BasicType BasicType { get; init; }
}
public class OnArrayTypeGeneratorEventArgs : EventArgs
{
public required Period Period { get; init; }
public required BasicType BasicType { get; init; }
}
public class TypeSyntaxNode : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.Type;
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
RaiseEvent();
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
RaiseEvent();
}
public event EventHandler<OnBasicTypeGeneratorEventArgs>? OnBasicTypeGenerator;
public event EventHandler<OnArrayTypeGeneratorEventArgs>? OnArrayTypeGenerator;
private PascalType? _pascalType;
/// <summary>
/// Type节点制定的类型
/// </summary>
/// <exception cref="InvalidOperationException"></exception>
public PascalType PascalType
{
get
{
if (_pascalType is null)
{
throw new InvalidOperationException();
}
return _pascalType;
}
set
{
_pascalType = value;
}
}
public static TypeSyntaxNode Create(List<SyntaxNodeBase> children)
{
return new TypeSyntaxNode { Children = children };
}
private void RaiseEvent()
{
if (Children.Count == 1)
{
OnBasicTypeGenerator?.Invoke(this, new OnBasicTypeGeneratorEventArgs
{
BasicType = Children[0].Convert<BasicType>()
});
}
else
{
OnArrayTypeGenerator?.Invoke(this, new OnArrayTypeGeneratorEventArgs
{
Period = Children[2].Convert<Period>(),
BasicType = Children[5].Convert<BasicType>()
});
}
OnBasicTypeGenerator = null;
OnArrayTypeGenerator = null;
}
public override void GenerateCCode(CCodeBuilder builder)
{
//type -> basic_type
@@ -22,7 +97,6 @@ public class TypeSyntaxNode : NonTerminatedSyntaxNode
//type -> array [ period ]of basic_type
else
{
}
}
}

View File

@@ -1,5 +1,7 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
namespace Canon.Core.SyntaxNodes;
@@ -8,23 +10,27 @@ public class ValueParameter : NonTerminatedSyntaxNode
public override NonTerminatorType Type => NonTerminatorType.ValueParameter;
/// <summary>
/// 声明的变量列表
/// 是否为参数中的引用参数
/// </summary>
// public IdentifierList IdentifierList => Children[1].Convert<IdentifierList>();
public bool IsReference { get; set; }
/// <summary>
/// 声明的变量类型
/// </summary>
// public BasicType BasicType => Children[2].Convert<BasicType>();
public IdentifierSemanticToken Token =>
Children[0].Convert<TerminatedSyntaxNode>().Token.Convert<IdentifierSemanticToken>();
public IdentifierList IdentifierList => Children[1].Convert<IdentifierList>();
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static ValueParameter Create(List<SyntaxNodeBase> children)
{
return new ValueParameter { Children = children };
}
public override void GenerateCCode(CCodeBuilder builder)
{
//可能涉及符号表访问
builder.AddString("valueParam ");
}
}

View File

@@ -1,4 +1,6 @@
using Canon.Core.Enums;
using Canon.Core.Abstractions;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
namespace Canon.Core.SyntaxNodes;
@@ -6,42 +8,39 @@ public class VarDeclaration : NonTerminatedSyntaxNode
{
public override NonTerminatorType Type => NonTerminatorType.VarDeclaration;
// public bool IsRecursive { get; private init; }
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
// /// <summary>
// /// 声明的变量
// /// </summary>
// public (IdentifierList, TypeSyntaxNode) Variable => GetVariable();
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
// private (IdentifierList, TypeSyntaxNode) GetVariable()
// {
// if (IsRecursive)
// {
// return (Children[2].Convert<IdentifierList>(), Children[4].Convert<TypeSyntaxNode>());
// }
// else
// {
// return (Children[0].Convert<IdentifierList>(), Children[2].Convert<TypeSyntaxNode>());
// }
// }
public required IdentifierSemanticToken Token { get; init; }
public required IdentifierList IdentifierList { get; init; }
public static VarDeclaration Create(List<SyntaxNodeBase> children)
{
/*bool isRecursive;
if (children.Count == 2)
{
isRecursive = false;
}
else if (children.Count == 4)
{
isRecursive = true;
return new VarDeclaration
{
Children = children,
Token = children[0].Convert<TerminatedSyntaxNode>().Token.Convert<IdentifierSemanticToken>(),
IdentifierList = children[1].Convert<IdentifierList>()
};
}
else
{
throw new InvalidOperationException();
}*/
return new VarDeclaration {Children = children};
return new VarDeclaration
{
Children = children,
Token = children[2].Convert<TerminatedSyntaxNode>().Token.Convert<IdentifierSemanticToken>(),
IdentifierList = children[3].Convert<IdentifierList>()
};
}
}
}

View File

@@ -1,4 +1,5 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
using Canon.Core.SemanticParser;
@@ -13,6 +14,16 @@ public class VarDeclarations : NonTerminatedSyntaxNode
/// </summary>
// public IEnumerable<(IdentifierList, TypeSyntaxNode)> Variables => EnumerateVariables();
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static VarDeclarations Create(List<SyntaxNodeBase> children)
{
return new VarDeclarations { Children = children };

View File

@@ -1,4 +1,5 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.CodeGenerators;
using Canon.Core.Enums;
namespace Canon.Core.SyntaxNodes;
@@ -9,6 +10,16 @@ public class VarParameter : NonTerminatedSyntaxNode
public ValueParameter ValueParameter => Children[1].Convert<ValueParameter>();
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static VarParameter Create(List<SyntaxNodeBase> children)
{
return new VarParameter { Children = children };

View File

@@ -1,7 +1,6 @@
using Canon.Core.CodeGenerators;
using Canon.Core.Abstractions;
using Canon.Core.Enums;
using Canon.Core.LexicalParser;
using Canon.Core.SemanticParser;
namespace Canon.Core.SyntaxNodes;
@@ -15,48 +14,18 @@ public class Variable : NonTerminatedSyntaxNode
public IdentifierSemanticToken Identifier =>
(IdentifierSemanticToken)Children[0].Convert<TerminatedSyntaxNode>().Token;
public override void PreVisit(SyntaxNodeVisitor visitor)
{
visitor.PreVisit(this);
}
public override void PostVisit(SyntaxNodeVisitor visitor)
{
visitor.PostVisit(this);
}
public static Variable Create(List<SyntaxNodeBase> children)
{
return new Variable { Children = children };
}
public override void GenerateCCode(CCodeBuilder builder)
{
//判断是否为引用变量
builder.SymbolTable.TryGetSymbol(Identifier.IdentifierName, out var symbol);
if (symbol is not null && symbol.Reference)
{
builder.AddString(" (*" + Identifier.IdentifierName + ")");
}
else
{
builder.AddString(" " + Identifier.IdentifierName);
}
//处理idVarPart数组下标部分
var idVarPart = Children[1].Convert<IdentifierVarPart>();
if (idVarPart.Exist)
{
PascalArrayType pascalArrayType = (PascalArrayType)symbol.SymbolType;
var positions = idVarPart.Positions;
foreach (var pos in positions.Reverse())
{
builder.AddString("[");
pos.GenerateCCode(builder);
//pascal下标减去左边界从而映射到C语言的下标
builder.AddString(" - " + System.Convert.ToString(pascalArrayType.Begin) + "]");
try
{
pascalArrayType = (PascalArrayType)pascalArrayType.ElementType;
}
catch (InvalidCastException e)
{
//do nothing
//因为最后一层嵌套类型必然不是PascalArrayType, 而是BasicType
}
}
}
}
}