Exemple #1
0
 public IEnumerable <Bytecode> Compile(Parser.RegularExpression e)
 {
     this.groupcounter = 0;
     this.labelcounter = 0;
     foreach (var item in InternalCompile(e))
     {
         yield return(item);
     }
     yield return(new Match {
     });
 }
Exemple #2
0
        private IEnumerable <Bytecode> InternalCompile(Parser.RegularExpression e)
        {
            if (e is Parser.Primitive)
            {
                var prim = e as Parser.Primitive;
                yield return(new Symbol {
                    Lo = prim.Lo, Hi = prim.Hi
                });
            }
            else if (e is Parser.Sequence)
            {
                var seq   = e as Parser.Sequence;
                var left  = InternalCompile(seq.Left);
                var right = InternalCompile(seq.Right);
                foreach (var item in left.Concat(right))
                {
                    yield return(item);
                }
            }
            else if (e is Parser.Group)
            {
                var group = e as Parser.Group;
                var id    = this.groupcounter++;
                yield return(new Save {
                    Id = 2 * id
                });

                foreach (var item in InternalCompile(group.Re))
                {
                    yield return(item);
                }
                yield return(new Save {
                    Id = 2 * id + 1
                });
            }
            else if (e is Parser.Or)
            {
                var choice = e as Parser.Or;
                var l1     = new Label {
                    Location = this.labelcounter++
                };
                var l2 = new Label {
                    Location = this.labelcounter++
                };
                var l3 = new Label {
                    Location = this.labelcounter++
                };

                var e1 = InternalCompile(choice.Left);
                var e2 = InternalCompile(choice.Right);

                yield return(new Fork {
                    Fst = l1, Snd = l2
                });

                yield return(l1);

                foreach (var item in e1)
                {
                    yield return(item);
                }
                yield return(new Jump {
                    Where = l3
                });

                yield return(l2);

                foreach (var item in e2)
                {
                    yield return(item);
                }
                yield return(l3);
            }
            else if (e is Parser.Star)
            {
                var star = e as Parser.Star;

                var l1 = new Label {
                    Location = this.labelcounter++
                };
                var l2 = new Label {
                    Location = this.labelcounter++
                };
                var l3 = new Label {
                    Location = this.labelcounter++
                };

                var e1 = InternalCompile(star.Re);

                yield return(l1);

                if (star.Greedy)
                {
                    yield return new Fork {
                               Fst = l2, Snd = l3, Greedy = true
                    }
                }
                ;
                else
                {
                    yield return new Fork {
                               Fst = l3, Snd = l2, Greedy = false
                    }
                };
                yield return(l2);

                foreach (var item in e1)
                {
                    yield return(item);
                }
                yield return(new Jump {
                    Where = l1
                });

                yield return(l3);
            }
            else if (e is Parser.Plus)
            {
                var plus = e as Parser.Plus;

                var l1 = new Label {
                    Location = this.labelcounter++
                };
                var l2 = new Label {
                    Location = this.labelcounter++
                };
                var l3 = new Label {
                    Location = this.labelcounter++
                };

                var e1 = InternalCompile(plus.Re);
                yield return(l1);

                foreach (var item in e1)
                {
                    yield return(item);
                }
                if (plus.Greedy)
                {
                    yield return new Fork {
                               Fst = l1, Snd = l3, Greedy = true
                    }
                }
                ;
                else
                {
                    yield return new Fork {
                               Fst = l3, Snd = l1, Greedy = false
                    }
                };
                yield return(l3);
            }
            else if (e is Parser.Question)
            {
                throw new Exception("Finish types");
            }
            yield break;
        }