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 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 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 }; } public override void GenerateCCode(CCodeBuilder builder) { //获取常量值 var token = Children[0].Convert().Token; //constValue -> 'letter' if (token.TokenType == SemanticTokenType.Character) { builder.AddString(" '" + token.LiteralValue + "'"); } else { builder.AddString(" "); // constValue -> +num | -num | num foreach (var c in Children) { builder.AddString(c.Convert().Token.LiteralValue); } } } }