1 // =================================
  2 // Copyright (c) 2025 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 using System.Collections;
  8 
  9 namespace System.RegularExpressions
 10 {
 11     public const uchar eps = '\0';
 12 
 13     public abstract class Symbol
 14     {
 15         public virtual default ~Symbol();
 16         public abstract bool Match(uchar c);
 17     }
 18 
 19     public class Char : Symbol
 20     {
 21         public Char(uchar chr_) : chr(chr_)
 22         {
 23         }
 24         public inline uchar Chr() const
 25         {
 26             return chr;
 27         }
 28         public override bool Match(uchar c)
 29         {
 30             return c == chr;
 31         }
 32         private uchar chr;
 33     }
 34 
 35     public class Any : Symbol
 36     {
 37         public override bool Match(uchar c)
 38         {
 39             return true;
 40         }
 41     }
 42 
 43     public class Range : Symbol
 44     {
 45         public Range(uchar start_uchar end_) : start(start_)end(end_)
 46         {
 47         }
 48         public inline uchar Start() const
 49         {
 50             return start;
 51         }
 52         public inline uchar End() const
 53         {
 54             return end;
 55         }
 56         public override bool Match(uchar c)
 57         {
 58             return c >= start && c <= end;
 59         }
 60         private uchar start;
 61         private uchar end;
 62     }
 63 
 64     public inline bool operator==(const Range& leftconst Range& right)
 65     {
 66         return left.Start() == right.Start() && left.End() == right.End();
 67     }
 68 
 69     public inline bool operator<(const Range& leftconst Range& right)
 70     {
 71         if (left.Start() < right.Start()) return true;
 72         if (left.Start() > right.Start()) return false;
 73         return left.End() < right.End();
 74     }
 75 
 76     public class Class : Symbol
 77     {
 78         public Class() : inverse(false)
 79         {
 80         }
 81         public inline bool Inverse() const
 82         {
 83             return inverse;
 84         }
 85         public void SetInverse()
 86         {
 87             inverse = true;
 88         }
 89         public void AddSymbol(Symbol* symbol)
 90         {
 91             symbols.Add(symbol);
 92         }
 93         public override bool Match(uchar c)
 94         {
 95             bool match = false;
 96             for (Symbol* symbol : symbols)
 97             {
 98                 if (symbol->Match(c))
 99                 {
100                     match = true;
101                     break;
102                 }
103             }
104             return match != inverse;
105         }
106         private bool inverse;
107         private List<Symbol*> symbols;
108     }
109