using Canon.Core.Abstractions; using Canon.Core.Enums; using Canon.Core.LexicalParser; using Canon.Core.SemanticParser; namespace Canon.Core.SyntaxNodes; public class NumberGeneratorEventArgs : EventArgs { public required NumberSemanticToken Token { get; init; } } public class VariableGeneratorEventArgs : EventArgs { public required Variable Variable { get; init; } } public class ParethnesisGeneratorEventArgs : EventArgs { public required Expression Expression { get; init; } } public class NoParameterProcedureCallGeneratorEventArgs : EventArgs { public required IdentifierSemanticToken ProcedureName { get; init; } } public class ProcedureCallGeneratorEventArgs : EventArgs { public required IdentifierSemanticToken ProcedureName { get; init; } public required ExpressionList Parameters { get; init; } } public class NotGeneratorEventArgs : EventArgs { public required Factor Factor { get; init; } } public class UminusGeneratorEventArgs : EventArgs { public required Factor Factor { get; init; } } public class PlusGeneratorEventArgs : EventArgs { public required Factor Factor { get; init; } } public class BooleanGeneratorEventArgs : EventArgs { public required bool Value { 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(); } /// /// 使用数值产生式的事件 /// public event EventHandler? OnNumberGenerator; /// /// 使用括号产生式的事件 /// public event EventHandler? OnParethnesisGenerator; /// /// 使用变量产生式的事件 /// public event EventHandler? OnVariableGenerator; /// /// 使用否定产生式的事件 /// public event EventHandler? OnNotGenerator; /// /// 使用负号产生式的事件 /// public event EventHandler? OnUminusGenerator; /// /// 使用加号产生式的事件 /// public event EventHandler? OnPlusGenerator; /// /// 使用布尔值产生式的事件 /// public event EventHandler? OnBooleanGenerator; /// /// 没有参数的过程调用产生式事件 /// public event EventHandler? OnNoParameterProcedureCallGenerator; /// /// 过程调用产生式的事件 /// public event EventHandler? OnProcedureCallGenerator; private PascalType? _factorType; public PascalType FactorType { get { if (_factorType is null) { throw new InvalidOperationException(); } return _factorType; } set { _factorType = value; } } public static Factor Create(List children) { return new Factor { Children = children }; } private void RaiseEvent() { if (Children.Count == 1) { if (Children[0].IsTerminated) { SemanticToken token = Children[0].Convert().Token; switch (token.TokenType) { // factor -> num case SemanticTokenType.Number: OnNumberGenerator?.Invoke(this, new NumberGeneratorEventArgs { Token = token.Convert() }); break; // factor -> true | false case SemanticTokenType.Keyword: KeywordSemanticToken keywordSemanticToken = token.Convert(); switch (keywordSemanticToken.KeywordType) { case KeywordType.True: OnBooleanGenerator?.Invoke(this, new BooleanGeneratorEventArgs { Value = true }); break; case KeywordType.False: OnBooleanGenerator?.Invoke(this, new BooleanGeneratorEventArgs { Value = false }); break; } break; } } else { OnVariableGenerator?.Invoke(this, new VariableGeneratorEventArgs { Variable = Children[0].Convert() }); } } else if (Children.Count == 3) { TerminatedSyntaxNode terminatedSyntaxNode = Children[0].Convert(); // factor -> ( expression ) if (terminatedSyntaxNode.Token.TokenType == SemanticTokenType.Delimiter) { OnParethnesisGenerator?.Invoke(this, new ParethnesisGeneratorEventArgs { Expression = Children[1].Convert() }); } else { // factor -> id ( ) OnNoParameterProcedureCallGenerator?.Invoke(this, new NoParameterProcedureCallGeneratorEventArgs { ProcedureName = terminatedSyntaxNode.Token.Convert() }); } } else if (Children.Count == 4) { // factor -> id ( expressionList) OnProcedureCallGenerator?.Invoke(this, new ProcedureCallGeneratorEventArgs { ProcedureName = Children[0].Convert().Token.Convert(), Parameters = Children[2].Convert() }); } else { SemanticToken token = Children[0].Convert().Token; Factor factor = Children[1].Convert(); if (token.TokenType == SemanticTokenType.Keyword) { // factor -> not factor OnNotGenerator?.Invoke(this, new NotGeneratorEventArgs { Factor = factor }); } else { OperatorSemanticToken operatorSemanticToken = token.Convert(); switch (operatorSemanticToken.OperatorType) { // factor -> + factor case OperatorType.Plus: OnPlusGenerator?.Invoke(this, new PlusGeneratorEventArgs { Factor = factor }); break; // factor -> - factor case OperatorType.Minus: OnUminusGenerator?.Invoke(this, new UminusGeneratorEventArgs { Factor = factor }); break; } } } OnNumberGenerator = null; OnVariableGenerator = null; OnParethnesisGenerator = null; OnProcedureCallGenerator = null; OnNotGenerator = null; OnUminusGenerator = null; } }