Exemplo n.º 1
0
 public void PushCurrent(QNode newCurrent)
 {
     if (current != null)
       prevElements.Add(current);
     current = newCurrent;
 }
Exemplo n.º 2
0
        public static QNode[] Parse(string text, int index = 0, int state = 0)
        {
            var stack = new Stack<ParseInfo>();
              var info = new ParseInfo();

              Action PopWhileSingle = () =>
              {
            for (; stack.Count > 0 && info.isSingle == true; )
            {
              var parent = stack.Pop();
              parent.PushChild(info);
              info = parent;
            }
              };
              var lexemBuilder = new System.Text.StringBuilder();
              for (; ; )
              {
            char ch = index < text.Length ? text[index] : (char)0;
            var isEnd = index >= text.Length;
            if (state == 0)
            {
              if (index >= text.Length)
              {
            PopWhileSingle();
            if (stack.Count > 0)
              throw new Exception($"Не хватает закрывающихся скобок - '{stack.Count}' шт.");

            return info.allElements;
              }
              else if (char.IsWhiteSpace(ch))
              {
            index++;
            continue;
              }
              else if (ch == Quote)
              {
            state = 2;
            lexemBuilder = new System.Text.StringBuilder();
            index++;
            continue;
              }
              else if (ch == DoubleQuote)
              {
            state = 3;
            lexemBuilder = new System.Text.StringBuilder();
            index++;
            continue;
              }
              else if (char.IsLetter(ch) || char.IsDigit(ch) || ch == '-' || ch == '_')
              {
            state = 1;
            lexemBuilder = new System.Text.StringBuilder();
            lexemBuilder.Append(ch);
            index++;
            continue;
              }
              else if (ch == ':' && (index + 1) < text.Length && text[index + 1] == ':')
              {
            state = 1;
            lexemBuilder = new System.Text.StringBuilder();
            lexemBuilder.Append(text.Substring(index, 2));
            index += 2;
              }
              else if (ch == ':')
              {
            stack.Push(info);
            info = new ParseInfo { isSingle = true };
            index++;
            continue;
              }
              else if (ch == '{' || ch == '(')
              {
            stack.Push(info);
            info = new ParseInfo();
            index++;
            continue;
              }
              else if (ch == '}' || ch == ')')
              {
            PopWhileSingle();
            var parentInfo = stack.Pop();
            parentInfo.PushChild(info);
            info = parentInfo;
            index++;
            continue;
              }
              else if (ch == ',' || ch == ';')
              {
            PopWhileSingle();
            info.PushCurrent(null);
            index++;
            continue;
              }
              else if (ch == '/' && (index + 1) < text.Length && text[index + 1] == '/')
              {
            state = 4;
            lexemBuilder = new System.Text.StringBuilder();
            index += 2;
            continue;
              }
              else
              {
            throw new Exception(string.Format("invalid char in index:{0}", index));
            //index++;
            //continue;
              }
            }
            else if (state == 1)
            {
              if (char.IsLetter(ch) || char.IsDigit(ch) || ch == '-' || ch == '_')
              {
            lexemBuilder.Append(ch);
            index++;
            continue;
              }
              else
              {
            var q = new QNode(lexemBuilder.ToString());
            info.PushCurrent(q);
            state = 0;
            continue;
              }
            }
            else if (state == 2 || state == 3)
            {
              var quote = state == 2 ? Quote : DoubleQuote;
              if (isEnd)
            throw new Exception(string.Format("не законченная строка '{0}'", lexemBuilder));
              else if (ch == quote)
              {
            if ((index + 1) < text.Length && text[index + 1] == quote)
            {
              lexemBuilder.Append(quote);
              index += 2;
              continue;
            }
            else
            {
              var q = new QNode(lexemBuilder.ToString());
              info.PushCurrent(q);
              state = 0;
              index++;
              continue;
            }
              }
              else
              {
            lexemBuilder.Append(ch);
            index++;
            continue;
              }
            }
            else if (state == 4)
            {
              if (ch == '\r' || ch == '\n')
              {
            //var q = new QElement(lexemBuilder.ToString());
            //info.PushCurrent(q);
            state = 0;
            index++;
            continue;
              }
              else
              {
            lexemBuilder.Append(ch);
            index++;
            continue;
              }
            }

              }
        }