@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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 };
|
||||
}
|
||||
}
|
||||
|
@@ -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 };
|
||||
|
@@ -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;
|
||||
|
@@ -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 };
|
||||
|
@@ -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 };
|
||||
|
@@ -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 };
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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(" /");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -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()
|
||||
|
@@ -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>();
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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 };
|
||||
|
@@ -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 };
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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 };
|
||||
|
@@ -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:
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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;
|
||||
|
@@ -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 };
|
||||
|
@@ -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 };
|
||||
|
@@ -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 };
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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()
|
||||
|
@@ -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)
|
||||
|
@@ -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()
|
||||
|
@@ -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
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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 ");
|
||||
}
|
||||
}
|
||||
|
@@ -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>()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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 };
|
||||
|
@@ -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 };
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user