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;
}
}