Esempio n. 1
0
 public PairAwareState GetPairsState()
 {
     return(new PairAwareState()
     {
         CurrentTokenDirection = CurrentTokenDirection,
         PairStack = new Stack <PairSymbol>(PairStack.Reverse()),
         OpenedPair = OpenedPair
     });
 }
Esempio n. 2
0
        private List <int[]> MergeFromList(List <Tuple <int, string> > list)
        {
            var result = new List <int[]>();
            var stack  = new PairStack();

            for (int i = 0; i < list.Count; i++)
            {
                if (0 == list[i].Item2.CompareTo(FRONT))
                {
                    stack.Push(list[i]);
                }
                else
                {
                    Tuple <int, string> lastF = stack.Pop();

                    if (stack.IsEmpty(stack))
                    {
                        result.Add(MakeElement(Front: lastF, Back: list[i]));
                    }
                }
            }

            return(result);
        }
Esempio n. 3
0
 public bool IsEmpty(PairStack stack)
 {
     return(stack.Count == 0);
 }
Esempio n. 4
0
        public override IToken GetNextToken()
        {
            switch (CurrentTokenDirection)
            {
            case Direction.Down:
                PairStack.Push(OpenedPair);
                OpenedPair = null;
                break;

            case Direction.Up:
                PairStack.Pop();
                break;
            }

            CurrentTokenDirection = Direction.Forward;

            var token = base.GetNextToken();

            if (CustomBlockDefinition != null &&
                CustomBlockDefinition.BaseToken == token.Name)
            {
                if (CustomBlockDefinition.IsStartLexem(token.Text))
                {
                    var newBlock = new CustomBlockNode
                    {
                        Location = new SegmentLocation {
                            Start = token.Location.Start
                        },
                        Start = new Node(token.Name, new LocalOptions {
                            ExactMatch = true, Priority = LocalOptions.BASE_PRIORITY
                        })
                    };

                    newBlock.Start.SetLocation(token.Location.Start, token.Location.End);
                    newBlock.Start.SetValue(CustomBlockDefinition.GetName(token.Text));

                    CustomBlockStack.Push(newBlock);
                }
                else if (CustomBlockDefinition.IsEndLexem(token.Text))
                {
                    /// Отлавливаем ситуацию, когда количество закрытий блока не совпадает с количеством открытий
                    if (CustomBlockStack.Count == 0)
                    {
                        Log.Add(Message.Error(
                                    $"Неожиданная закрывающая конструкция {this.GetTokenInfoForMessage(token)} для пользовательского блока",
                                    token.Location.Start
                                    ));
                    }
                    else
                    {
                        var currentBlock = CustomBlockStack.Pop();

                        currentBlock.End = new Node(token.Name);
                        currentBlock.End.SetLocation(token.Location.Start, token.Location.End);
                        currentBlock.Location.End = token.Location.End;

                        CustomBlocks.Add(currentBlock);
                    }
                }
            }

            /// Предполагается, что токен может быть началом ровно одной пары, или концом ровно одной пары,
            /// или одновременно началом и концом ровно одной пары
            var closed = GrammarObject.Pairs.FirstOrDefault(p => p.Value.Right.Contains(token.Name));

            /// Если текущий токен закрывает некоторую конструкцию
            if (closed.Value != null)
            {
                /// и при этом не открывает её же
                if (!closed.Value.Left.Contains(token.Name))
                {
                    /// проверяем, есть ли на стеке то, что можно этой конструкцией закрыть
                    if (PairStack.Count == 0)
                    {
                        Log.Add(Message.Error(
                                    $"Отсутствует открывающая конструкция для парной закрывающей {this.GetTokenInfoForMessage(token)}",
                                    token.Location.Start
                                    ));

                        return(Lexer.CreateToken(Grammar.ERROR_TOKEN_NAME));
                    }
                    else if (PairStack.Peek() != closed.Value)
                    {
                        Log.Add(Message.Error(
                                    $"Неожиданная закрывающая конструкция {this.GetTokenInfoForMessage(token)}, ожидается {String.Join("или ", PairStack.Peek().Right.Select(e => GrammarObject.Userify(e)))} для открывающей конструкции {String.Join("или ", PairStack.Peek().Left.Select(e => GrammarObject.Userify(e)))}",
                                    token.Location.Start
                                    ));

                        return(Lexer.CreateToken(Grammar.ERROR_TOKEN_NAME));
                    }
                    else
                    {
                        CurrentTokenDirection = Direction.Up;
                    }
                }
                /// иначе, если текущий токен одновременно открывающий и закрывающий
                else
                {
                    /// и есть что закрыть, закрываем
                    if (PairStack.Count > 0 && PairStack.Peek() == closed.Value)
                    {
                        CurrentTokenDirection = Direction.Up;
                    }
                    else
                    {
                        CurrentTokenDirection = Direction.Down;
                        OpenedPair            = closed.Value;
                    }
                }
            }
            else
            {
                var opened = GrammarObject.Pairs.FirstOrDefault(p => p.Value.Left.Contains(token.Name));

                if (opened.Value != null)
                {
                    CurrentTokenDirection = Direction.Down;
                    OpenedPair            = opened.Value;
                }
            }

            return(token);
        }