Пример #1
0
 protected EmptyParser(EmptyParser other, ParserCloneArgs args)
     : base(other, args)
 {
 }
Пример #2
0
        void FixRecursiveGrammars()
        {
            var empty      = new EmptyParser();
            var alternates = Children.OfType <AlternativeParser>();
            var first      = new List <Parser>();
            var second     = new List <Parser>();

            foreach (var alt in alternates.Distinct().ToList())
            {
                first.Clear();
                second.Clear();
                Parser separator = null;
                for (int i = 0; i < alt.Items.Count; i++)
                {
                    Parser item = alt.Items[i];
                    if (item != null && item.IsLeftRecursive(alt))
                    {
                        var seqs = item.Scan(filter: p => {
                            if (ReferenceEquals(p, alt))
                            {
                                return(false);
                            }
                            if (p is SequenceParser seq && seq.Items.Count > 0 && seq.Items[0].IsLeftRecursive(alt))
                            {
                                seq.Items[0] = empty;
                                return(true);
                            }

                            return(false);
                        }).OfType <SequenceParser>();
                        foreach (var seq in seqs)
                        {
                            separator = seq.Separator;
                            seq.Items.RemoveAt(0);
                        }
                        if (!item.IsLeftRecursive(alt))
                        {
                            second.Add(item);
                        }
                        else
                        {
                            Debug.WriteLine(string.Format("Warning: Item in alternate is still recursive {0}", item.DescriptiveName));
                        }
                    }
                    else
                    {
                        first.Add(item);
                    }
                }

                if (second.Count > 0)
                {
                    Debug.WriteLine(string.Format("Fixing recursion in alternate: {0}", alt.DescriptiveName));
                    alt.Items.Clear();
                    var secondParser = second.Count > 1 ? new AlternativeParser(second) : second[0];
                    if (first.Count > 0)
                    {
                        var firstParser = first.Count > 1 ? new AlternativeParser(first) : first[0];
                        var repeat      = new RepeatParser(secondParser, 0)
                        {
                            Separator = separator
                        };

                        if (first.Count == 1 && first[0] == null)
                        {
                            alt.Items.Add(repeat);
                        }
                        else
                        {
                            alt.Items.Add(new SequenceParser(firstParser, repeat)
                            {
                                Separator = separator
                            });
                        }
                    }
                    else
                    {
                        alt.Items.Add(new RepeatParser(secondParser, 1)
                        {
                            Separator = separator
                        });
                    }
                }
            }
        }
Пример #3
0
 private bool Accept <TInput>(EmptyParser <TInput> p, BnfStringifyVisitor state)
 {
     state.Append("()");
     return(true);
 }
Пример #4
0
		protected EmptyParser(EmptyParser other, ParserCloneArgs args)
			: base(other, args)
		{
		}