Advertisement
whitelava3203

test cs

Dec 27th, 2023
600
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 16.71 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Reflection.Metadata.Ecma335;
  6. using System.Text;
  7. using System.Threading;
  8. using System.Threading.Channels;
  9. using System.Threading.Tasks;
  10.  
  11. namespace MPL
  12. {
  13.  
  14.     public class ScriptReader : IEnumerable<Ranged<string>>
  15.     {
  16.         char[] Src;
  17.         int index;
  18.  
  19.         public ScriptReader(string src)
  20.         {
  21.             this.Src = src.ToCharArray();
  22.             index = 0;
  23.         }
  24.  
  25.         public ScriptReader(char[] src, int index)
  26.         {
  27.             this.Src = src;
  28.             index = 0;
  29.         }
  30.  
  31.         public bool TryReadNext(out Ranged<string> output)
  32.         {
  33.             output = null;
  34.            
  35.  
  36.             //index 는 시작지점, curr은 길이
  37.  
  38.             int curr = 0;
  39.             int currIndex() => index + curr;
  40.             char currWord() => Src[currIndex()];
  41.  
  42.             if (currIndex() >= Src.Length)
  43.             {
  44.                 return false;
  45.             }
  46.  
  47.             //초기 IgnoreWord 제거
  48.             while (true)
  49.             {
  50.                 if (currIndex() >= Src.Length)
  51.                 {
  52.                     return false;
  53.                 }
  54.                 else if (IgnoreWords.Contains(currWord()))
  55.                 {
  56.                     curr++;
  57.                 }
  58.                 else
  59.                 {
  60.                     break;
  61.                 }
  62.             }
  63.  
  64.             //시작이 UsedWords일경우 바로 반환
  65.             if (UsedWords.Contains(currWord()))
  66.             {
  67.                 output = new Ranged<string>(currWord().ToString(), index..currIndex());
  68.                 index += curr + 1;
  69.                
  70.                 return true;
  71.             }
  72.  
  73.  
  74.  
  75.             int beginIndex = currIndex();
  76.  
  77.  
  78.             //시작이 "일경우 다음 "까지 쭉 달림
  79.             if (currWord() == '\"')
  80.             {
  81.                 curr++;
  82.                 while(currWord() != '\"')
  83.                 {
  84.                     curr++;
  85.                 }
  86.                 curr++;
  87.  
  88.                 output = new Ranged<string>(new(Src[beginIndex..currIndex()]), index..currIndex());
  89.  
  90.                 index += curr;
  91.                 return true;
  92.             }
  93.  
  94.  
  95.             curr++;
  96.  
  97.  
  98.            
  99.  
  100.             while (true)
  101.             {
  102.                 if (currIndex() >= Src.Length)
  103.                 {
  104.                     if (beginIndex == currIndex())
  105.                     {
  106.                         return false;
  107.                     }
  108.                     else
  109.                     {
  110.                         output = new Ranged<string>(new(Src[beginIndex..currIndex()]), index..currIndex());
  111.                         index += curr;
  112.                         return true;
  113.                     }
  114.                 }
  115.                 else if (UsedWords.Contains(currWord()) || IgnoreWords.Contains(currWord()))
  116.                 {
  117.                     output = new Ranged<string>(new(Src[beginIndex..currIndex()]), index..currIndex());
  118.                     index += curr;
  119.                     return true;
  120.                 }
  121.                 curr++;
  122.             }
  123.         }
  124.  
  125.         public string ReadNext()
  126.         {
  127.             TryReadNext(out Ranged<string> str);
  128.             return str;
  129.         }
  130.  
  131.         public IEnumerator<Ranged<string>> GetEnumerator()
  132.         {
  133.             while (this.TryReadNext(out Ranged<string> str))
  134.             {
  135.                 yield return str;
  136.             }
  137.             yield break;
  138.         }
  139.  
  140.         IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
  141.  
  142.         char[] UsedWords = new char[]
  143.         {
  144.             '.',
  145.             ',',
  146.             '<',
  147.             '>',
  148.             '/',
  149.             '?',
  150.             ':',
  151.             ';',
  152.             '\'',
  153.             '[',
  154.             ']',
  155.             '{',
  156.             '}',
  157.             '(',
  158.             ')',
  159.             '*',
  160.             '&',
  161.             '^',
  162.             '%',
  163.             '$',
  164.             '#',
  165.             '@',
  166.             '!',
  167.             '~',
  168.             '`',
  169.             '-',
  170.             '=',
  171.             '+',
  172.             '.',
  173.         };
  174.         char[] IgnoreWords = new char[]
  175.         {
  176.             ' ',
  177.             '\r',
  178.             '\n',
  179.             '\t',
  180.         };
  181.     }
  182.  
  183.  
  184.     public class FunctionReader : IEnumerable<string>
  185.     {
  186.         public ScriptReader reader;
  187.  
  188.         public enum Bracket
  189.         {
  190.             Small,
  191.             Medium,
  192.             Big,
  193.             Comparer
  194.         }
  195.  
  196.         public IEnumerator<string> GetEnumerator()
  197.         {
  198.             Stack<Bracket> stack = new Stack<Bracket>(32);
  199.             foreach(string text in this.reader)
  200.             {
  201.                 switch(text)
  202.                 {
  203.                     case "(":
  204.                         stack.Push(Bracket.Small);
  205.                         goto end;
  206.                     case "{":
  207.                         stack.Push(Bracket.Medium);
  208.                         goto end;
  209.                     case "[":
  210.                         stack.Push(Bracket.Big);
  211.                         goto end;
  212.                     case "<":
  213.                         stack.Push(Bracket.Comparer);
  214.                         goto end;
  215.  
  216.                     end:
  217.                         yield return text;
  218.                         break;
  219.  
  220.                     case ")":
  221.                         if (stack.Peek() != Bracket.Small)
  222.                             throw new Exception(stack.Peek() + "괄호가 더닫힘");
  223.                         stack.Pop();
  224.                         break;
  225.                     case "}":
  226.                         if (stack.Peek() != Bracket.Medium)
  227.                             throw new Exception(stack.Peek() + "괄호가 더닫힘");
  228.                         stack.Pop();
  229.                         break;
  230.                     case "]":
  231.                         if (stack.Peek() != Bracket.Big)
  232.                             throw new Exception(stack.Peek() + "괄호가 더닫힘");
  233.                         stack.Pop();
  234.                         break;
  235.                     case ">":
  236.                         if (stack.Peek() != Bracket.Comparer)
  237.                             throw new Exception(stack.Peek() + "괄호가 더닫힘");
  238.                         stack.Pop();
  239.                         break;
  240.                 }
  241.  
  242.                 if (stack.Count == 0)
  243.                     yield break;
  244.             }
  245.         }
  246.  
  247.         IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
  248.     }
  249.  
  250.  
  251.     public class ScriptBlockReader : IEnumerable<ScriptBlock>
  252.     {
  253.         ///작동방식
  254.         ///쭉 읽다가 ;나오면 블럭 반환
  255.         ///{ 나오면 닫힐때까지 읽고 블럭 반환
  256.         ///
  257.  
  258.         public ScriptBlockReader(ScriptReader reader)
  259.         {
  260.             this.reader = reader;
  261.         }
  262.  
  263.         ScriptReader reader;
  264.  
  265.         public ScriptBlock.Block Read()
  266.         {
  267.             return ReadSingleBlock(Bracket.Shape.EOF);
  268.         }
  269.  
  270.  
  271.  
  272.  
  273.  
  274.         private ScriptBlock.Block ReadSingleBlock(Bracket.Shape opener)
  275.         {
  276.             ScriptBlock.Block currentblock = new ScriptBlock.Block(opener);
  277.             ScriptBlock.Block eolBlock = null;
  278.             bool eolState = false;
  279.             foreach (var str in reader)
  280.             {
  281.                 ;
  282.                 if (str.o.Length == 1 && Bracket.Groups.TryGetValue(str.o[0], out (Bracket.Shape shape, Bracket.Location loc) val))
  283.                 {
  284.                     switch (val.loc)
  285.                     {
  286.                         case Bracket.Location.Open:
  287.                         open:
  288.                             var block = ReadSingleBlock(val.shape);
  289.  
  290.                             /*
  291.                             if(block.shape != Bracket.Shape.EOL)
  292.                             {
  293.                                 currentblock.Add(block);
  294.                             }
  295.                             */
  296.  
  297.  
  298.  
  299.                             if (block.shape == Bracket.Shape.EOL)
  300.                             {
  301.                                 if (!eolState)
  302.                                 {
  303.                                     eolBlock = new ScriptBlock.Block(val.shape);
  304.                                 }
  305.                                 eolState = true;
  306.                                 eolBlock.Add(block);
  307.                                 goto open;
  308.                             }
  309.  
  310.                             if (eolState)
  311.                             {
  312.                                 eolState = false;
  313.                                 block.ChangeShape(Bracket.Shape.EOL);
  314.                                 eolBlock.Add(block);
  315.                                 currentblock.Add(eolBlock);
  316.                             }
  317.                             else
  318.                             {
  319.                                 currentblock.Add(block);
  320.                             }
  321.  
  322.                             break;
  323.  
  324.                         case Bracket.Location.Close:
  325.                         close:
  326.                             if (val.shape == opener)
  327.                                 return currentblock;
  328.                             throw new Exception();
  329.  
  330.                         case Bracket.Location.Both:
  331.                             if (opener == val.shape)
  332.                                 goto close;
  333.                             else
  334.                                 goto open;
  335.  
  336.                         case Bracket.Location.CloseOnly:
  337.                             currentblock.ChangeShape(val.shape);
  338.                             return currentblock;
  339.  
  340.                         default:
  341.                             throw new Exception();
  342.                     }
  343.                 }
  344.                 else
  345.                 {
  346.                     currentblock.Add(new ScriptBlock.Value(str));
  347.                 }
  348.  
  349.             }
  350.             //eof
  351.             if (opener == Bracket.Shape.EOF) return currentblock;
  352.             throw new Exception();
  353.  
  354.  
  355.         }
  356.  
  357.         public IEnumerator<ScriptBlock> GetEnumerator()
  358.         {
  359.             yield return this.Read();
  360.             yield break;
  361.         }
  362.  
  363.         IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
  364.     }
  365.  
  366.     public interface ScriptBlock : IRangeInside
  367.     {
  368.  
  369.         public class Block : ScriptBlock, IEnumerable<ScriptBlock>
  370.         {
  371.             public Block(Bracket.Shape shape)
  372.             {
  373.                 this._shape = shape;
  374.             }
  375.             public void Add(ScriptBlock item)
  376.             {
  377.                
  378.                 if (item is Block block)
  379.                 {
  380.                     //if (block.values.Count > 0)
  381.                         values.Add(item);
  382.                 }
  383.                 else
  384.                 {
  385.                     values.Add(item);
  386.                 }
  387.             }
  388.             public void ChangeShape(Bracket.Shape shape)
  389.             {
  390.                 this._shape = shape;
  391.             }
  392.  
  393.             List<ScriptBlock> values = new List<ScriptBlock>();
  394.  
  395.             Bracket.Shape _shape;
  396.             public Bracket.Shape shape => _shape;
  397.  
  398.             public Range range => Ranged.Merge(values.ConvertAll(x => x.range));
  399.  
  400.             public override string ToString()
  401.             {
  402.                 StringBuilder sb = new StringBuilder();
  403.                 string s = Bracket.StringOf((shape, Bracket.Location.Open));
  404.                 if(s.Length>0)
  405.                 {
  406.                     sb.AppendLine();
  407.                     sb.Append(s);
  408.                     sb.AppendLine();
  409.                 }
  410.                
  411.                 foreach (var b in values)
  412.                 {
  413.                     switch(b)
  414.                     {
  415.                         case ScriptBlock.Block bb:
  416.                             sb.Append(bb.ToString());
  417.                             break;
  418.                         case ScriptBlock.Value vb:
  419.                             sb.Append(vb.ToString());
  420.                             sb.Append(" ");
  421.                             break;
  422.                     }
  423.                 }
  424.                 sb.Append(Bracket.StringOf((shape, Bracket.Location.Close)));
  425.                 sb.AppendLine();
  426.                 return sb.ToString();
  427.             }
  428.  
  429.             public IEnumerator<ScriptBlock> GetEnumerator() => this.values.GetEnumerator();
  430.  
  431.             IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
  432.         }
  433.         public class Value : ScriptBlock
  434.         {
  435.             public Value(Ranged<string> value)
  436.             {
  437.                 this.value = value;
  438.             }
  439.  
  440.             public Ranged<string> value;
  441.  
  442.             public Range range => value.range;
  443.  
  444.             public Ranged<string> ToRangedString()
  445.             {
  446.                 return this.value;
  447.             }
  448.             public override string ToString()
  449.             {
  450.                 return this.value;
  451.             }
  452.         }
  453.     }
  454.  
  455.  
  456.  
  457.     public static class Bracket
  458.     {
  459.         public enum Shape
  460.         {
  461.             Null,
  462.             None,
  463.             Small,
  464.             Medium,
  465.             Big,
  466.             Comparer,
  467.             String,
  468.             Char,
  469.             EOL,
  470.             EOF
  471.         }
  472.  
  473.         public enum Location
  474.         {
  475.             Null,
  476.             None,
  477.             Open,
  478.             Close,
  479.             CloseOnly,
  480.             Both
  481.         }
  482.  
  483.         public static Dictionary<char, (Shape, Location)> Groups = new()
  484.         {
  485.             ['('] = (Shape.Small, Location.Open),
  486.             [')'] = (Shape.Small, Location.Close),
  487.             ['{'] = (Shape.Medium, Location.Open),
  488.             ['}'] = (Shape.Medium, Location.Close),
  489.             ['['] = (Shape.Big, Location.Open),
  490.             [']'] = (Shape.Big, Location.Close),
  491.             ['<'] = (Shape.Comparer, Location.Open),
  492.             ['>'] = (Shape.Comparer, Location.Close),
  493.             [';'] = (Shape.EOL, Location.CloseOnly),
  494.             ['"'] = (Shape.String, Location.Both),
  495.             ['\''] = (Shape.Char, Location.Both),
  496.             [(char)0x00] = (Shape.EOF, Location.CloseOnly),
  497.         };
  498.  
  499.         public static string StringOf((Shape, Location) val)
  500.         {
  501.             switch(val.Item1)
  502.             {
  503.                 case Shape.Small:
  504.                     switch(val.Item2)
  505.                     {
  506.                         case Location.Open:
  507.                             return "(";
  508.                         case Location.Close:
  509.                             return ")";
  510.                         default:
  511.                             throw new Exception();
  512.                     }
  513.  
  514.                 case Shape.Medium:
  515.                     switch (val.Item2)
  516.                     {
  517.                         case Location.Open:
  518.                             return "{";
  519.                         case Location.Close:
  520.                             return "}";
  521.                         default:
  522.                             throw new Exception();
  523.                     }
  524.  
  525.                 case Shape.Big:
  526.                     switch (val.Item2)
  527.                     {
  528.                         case Location.Open:
  529.                             return "[";
  530.                         case Location.Close:
  531.                             return "]";
  532.                         default:
  533.                             throw new Exception();
  534.                     }
  535.  
  536.                 case Shape.Comparer:
  537.                     switch (val.Item2)
  538.                     {
  539.                         case Location.Open:
  540.                             return "<";
  541.                         case Location.Close:
  542.                             return ">";
  543.                         default:
  544.                             throw new Exception();
  545.                     }
  546.  
  547.                 case Shape.EOL:
  548.                     switch(val.Item2)
  549.                     {
  550.                         case Location.Open:
  551.                             return "";
  552.                         case Location.Close:
  553.                         case Location.CloseOnly:
  554.                             return ";";
  555.                         default:
  556.                             throw new Exception();
  557.                     }
  558.  
  559.                 case Shape.String:
  560.                     return "\"";
  561.  
  562.                 case Shape.Char:
  563.                     return "\'";
  564.  
  565.                 case Shape.EOF:
  566.                     switch (val.Item2)
  567.                     {
  568.                         case Location.Open:
  569.                             return "";
  570.                         case Location.Close:
  571.                         case Location.CloseOnly:
  572.                             return "#EOF#";
  573.                         default:
  574.                             throw new Exception();
  575.                     }
  576.  
  577.                 default:
  578.                     return "#NULL#";
  579.             }
  580.         }
  581.     }
  582.  
  583. }
  584.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement