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