Пример #1
0
        Pattern Deriv(Pattern p, Pattern c)
        {
            switch (p.Type)
            {
            case PatternType.NotAllowed:
                return(p);

            case PatternType.Empty:
                return(NotAllowed());

            case PatternType.Ref:
                return(c.Type == PatternType.Ref &&
                       p.Name == c.Name ? Empty() : NotAllowed());

            case PatternType.OneOrMore:
                return(Group(Deriv(p.p1, c), Optional(p)));

            case PatternType.Choice:
                return(Choice(Deriv(p.p1, c), Deriv(p.p2, c)));

            case PatternType.And:
                return(And(Deriv(p.p1, c), Deriv(p.p2, c)));

            case PatternType.Not:
                return(Not(Deriv(p.p1, c)));

            case PatternType.Group:

                if (c.Type == PatternType.Attribute)
                {
                    return(Choice(Group(Deriv(p.p1, c), p.p2),
                                  Group(p.p1, Deriv(p.p2, c))));
                }

                if (p.p1.Nullable)
                {
                    return(Choice(Deriv(p.p2, c), Group(Deriv(p.p1, c), p.p2)));
                }
                return(Group(Deriv(p.p1, c), p.p2));

            case PatternType.Text:
                return(NotAllowed());

            case PatternType.Attribute:
                return(c.Type == PatternType.Attribute &&
                       p.Name == c.Name ? Optional(p) : NotAllowed());

            case PatternType.Interleave:
                return(Choice(Interleave(Deriv(p.p1, c), p.p2),
                              Interleave(p.p1, Deriv(p.p2, c))));

            case PatternType.Define:
                return(Define(p.Name, Deriv(p.p1, c)));

            case PatternType.AnyName:
                return(p);

            case PatternType.LnName:
                return(c.Type == PatternType.LnName &&
                       c.Name == p.Name ? Empty() : NotAllowed());

            case PatternType.NsName:
                return(c.Type == PatternType.NsName &&
                       c.Namespace == p.Namespace ? Empty() : NotAllowed());

            default:
                throw new Exception();
            }
        }
Пример #2
0
        public State Simulate(Pattern elem)
        {
            if (Seen.Contains(elem))
            {
                return(Pattern2State [elem]);
            }

            var ElemState = new State()
            {
                IsNullable = elem.Nullable
            };
            var root = elem;

            if (!Pattern2State.ContainsKey(root))
            {
                Pattern2State.Add(root, ElemState);
            }

            Queue <Pattern> queue = new Queue <Pattern> ();

            queue.Enqueue(root);

            var leaves = elem.DescendantNodesAndSelf().Where(x =>
                                                             x.Type == PatternType.Attribute ||
                                                             x.Type == PatternType.Ref).Distinct().ToList();

            while (queue.Count > 0)
            {
                var current = queue.Dequeue();
                var cstate  = Pattern2State [current];

                if (Seen.Contains(current))
                {
                    continue;
                }

                current.DescendantNodesAndSelf()
                .Where(x => x.Type == PatternType.Define)
                .Where(x => x.Nullable)
                .ToList()
                .ForEach(x => cstate.NullableDefines.Add(x.Name));

                Seen.Add(current);

                foreach (var leaf in leaves)
                {
                    var derived = Deriv(current, leaf);

                    if (derived.Type == PatternType.NotAllowed)
                    {
                        continue;
                    }

                    if (!Pattern2State.ContainsKey(derived))
                    {
                        Pattern2State.Add(derived, new State()
                        {
                            IsNullable = derived.Nullable
                        });
                        queue.Enqueue(derived);
                    }

                    var dstate = Pattern2State [derived];

                    if (leaf.Type == PatternType.Attribute)
                    {
                        if (leaf.Namespace.Length > 0)
                        {
                            cstate.AttrStates.Add("{" + leaf.Namespace + "}" + leaf.Name, dstate);
                        }
                        else
                        {
                            cstate.AttrStates.Add(leaf.Name, dstate);
                        }
                    }
                    else if (leaf.Type == PatternType.Ref)
                    {
                        cstate.ChildStates.Add(leaf.Name, dstate);
                    }
                }
            }
            if (!Pattern2State.ContainsValue(ElemState))
            {
                throw new Exception();
            }
            return(ElemState);
        }
Пример #3
0
 Pattern Optional(Pattern p)
 {
     return(Choice(Empty(), p));
 }