예제 #1
0
파일: LR0.cs 프로젝트: martindevans/Hermes
        public static Automaton CreateAutomaton(Grammar g)
        {
            //initialise to closure of start item
            HashSet<ParseState> states = new HashSet<ParseState>();
            states.Add(g.Productions.Where(a => a.Head.Equals(g.Root)).Select(a => new Item(a, 0)).Closure(g));

            HashSet<ParseStateTransition> transitions = new HashSet<ParseStateTransition>();

            HashSet<ParseState> sToAdd = new HashSet<ParseState>();
            HashSet<ParseStateTransition> tToAdd = new HashSet<ParseStateTransition>();

            do
            {
                sToAdd.Clear();
                tToAdd.Clear();

                foreach (var state in states)
                {
                    foreach (var item in state)
                    {
                        if (item.Production.Body.Length == item.Position)
                            continue;

                        BnfTerm term = item.Production.Body[item.Position];
                        ParseState j = state.Goto(term, g);

                        sToAdd.Add(j);
                        tToAdd.Add(new ParseStateTransition(state, term, j));
                    }
                }
            }
            while (states.UnionWithAddedCount(sToAdd) != 0 | transitions.UnionWithAddedCount(tToAdd) != 0);

            return new Automaton(transitions, g);
        }
예제 #2
0
        public static ParseState Closure(this IEnumerable<Item> items, Grammar grammar)
        {
            HashSet<Item> closure = new HashSet<Item>(items);
            HashSet<Item> toAdd = new HashSet<Item>();

            do
            {
                toAdd.Clear();
                foreach (var item in closure)
                {
                    if (item.Position == item.Production.Body.Length)
                        continue;

                    BnfTerm term = item.Production.Body[item.Position];

                    if (term is NonTerminal)
                    {
                        NonTerminal nonTerm = term as NonTerminal;
                        foreach (var production in grammar.Productions.Where(a => a.Head.Equals(nonTerm)))
                            toAdd.Add(new Item(production, 0));
                    }
                }
            }
            while (closure.UnionWithAddedCount(toAdd) > 0);

            return new ParseState(closure, IsAcceptingState(closure, grammar));
        }
예제 #3
0
        public static Grammar ConstructTestGrammar(out NonTerminal S, out NonTerminal T, out NonTerminal F)
        {
            T = new NonTerminal("T");
            F = new NonTerminal("F");

            T.Rules = T + "*" + F | F;
            F.Rules = "(" + T + ")" | new Terminal("ID", "([A-Z]|[a-z])+");

            var g = new Grammar(T, new Terminal(" ", isIgnored:true));

            S = g.Root;

            return g;
        }
예제 #4
0
        public void GetFirstSetWithEmptyStrings()
        {
            NonTerminal a = new NonTerminal("A");
            NonTerminal b = new NonTerminal("B");

            a.Rules = b + "s";
            b.Rules = "".AsTerminal() | "x";

            Grammar g = new Grammar(a);
            var set = g.GetFirstSet(a);

            Assert.IsNotNull(set);
            Assert.AreEqual(2, set.Count);
            Assert.IsTrue(set.Contains("x"));
            Assert.IsTrue(set.Contains("s"));
        }
예제 #5
0
        private IEnumerable<Item> CalculateInitialState(out Grammar g, out NonTerminal S, out NonTerminal T, out NonTerminal F)
        {
            S = new NonTerminal("S");
            var sCopy = S;
            T = new NonTerminal("T");
            F = new NonTerminal("F");

            S.Rules = T + "$";
            T.Rules = T + "*" + F | F;
            F.Rules = "(" + T + ")" | new Terminal("ID", "([A-Z]|[a-z])+");

            g = new Grammar(S, new Terminal(" "));

            Item start = new Item(g.Productions.First(a => a.Head.Equals(sCopy)), 0);

            return new[] { start }.Closure(g);
        }
예제 #6
0
        public static ParseState Goto(this IEnumerable<Item> state, BnfTerm symbol, Grammar grammar)
        {
            HashSet<Item> items = new HashSet<Item>();

            foreach (var item in state)
            {
                if (item.Production.Body.Length == item.Position)
                    continue;

                BnfTerm term = item.Production.Body[item.Position];

                if (term.Equals(symbol))
                    items.Add(new Item(item.Production, item.Position + 1));
            }

            return items.Closure(grammar);
        }
예제 #7
0
        public void GetFirstSet()
        {
            NonTerminal a = new NonTerminal("A");
            NonTerminal b = new NonTerminal("B");
            NonTerminal c = new NonTerminal("C");
            NonTerminal d = new NonTerminal("D");

            a.Rules = b + d | c + d;
            b.Rules = "b";
            c.Rules = "c";
            d.Rules = "d";

            Grammar g = new Grammar(a);
            var set = g.GetFirstSet(a);

            Assert.IsNotNull(set);
            Assert.AreEqual(2, set.Count);
            Assert.IsFalse(set.Contains("d"));
            Assert.IsTrue(set.Contains("b"));
            Assert.IsTrue(set.Contains("c"));
        }
예제 #8
0
        public void ConstructAGrammar()
        {
            NonTerminal op = new NonTerminal("Operator");
            NonTerminal expr = new NonTerminal("Expression");

            Terminal number = new Terminal("Number", @"\b\d+\b");
            Terminal plus = new Terminal("Plus", @"\+");
            Terminal multiply = @"\*";

            op.Rules = plus | multiply;
            expr.Rules = number + op + expr;

            Terminal whitespace = new Terminal("Whitespace", " |\n|\r", true);
            Grammar g = new Grammar(expr, whitespace);

            Assert.AreEqual(3, g.Terminals.Count());
            Assert.AreEqual(3, g.NonTerminals.Count()); //Although the grammar only specifies 2 Nonterminals, grammar creates 1 internally for the root

            Lexer lexer = g.CreateLexer("1 + 2 * 3");

            Assert.AreEqual(5, lexer.Count());
        }
예제 #9
0
        public Automaton(IEnumerable<ParseStateTransition> transitions, Grammar grammar)
        {
            this.grammar = grammar;

            foreach (var transition in transitions)
            {
                allStates.Add(transition.Start);
                allStates.Add(transition.End);

                Dictionary<BnfTerm, ParseState> d;
                if (!transitionRules.TryGetValue(transition.Start, out d))
                {
                    d = new Dictionary<BnfTerm, ParseState>();
                    transitionRules.Add(transition.Start, d);
                }

                if (d.ContainsKey(transition.Trigger))
                    throw new InvalidOperationException("Duplicate transition");

                d[transition.Trigger] = transition.End;
            }
        }
예제 #10
0
        public void GetFollowSet()
        {
            NonTerminal a = new NonTerminal("A");
            NonTerminal b = new NonTerminal("B");

            a.Rules = "a" + b;
            b.Rules = b + "a" | "c";

            Grammar g = new Grammar(a);

            var followA = g.GetFollowSet(a);
            Assert.AreEqual(0, followA.Count);

            var followB = g.GetFollowSet(b);
            Assert.AreEqual(1, followB.Count);
            Assert.IsTrue(followB.Contains("a"));
        }
예제 #11
0
        public void IsNullable()
        {
            NonTerminal a = new NonTerminal("A");
            NonTerminal b = new NonTerminal("B");
            NonTerminal c = new NonTerminal("C");

            a.Rules = b + "s";
            b.Rules = "".AsTerminal() | c;
            c.Rules = "c";

            Grammar g = new Grammar(a);

            Assert.IsTrue(b.IsNullable);
            Assert.IsFalse(a.IsNullable);
            Assert.IsFalse(c.IsNullable);
        }
예제 #12
0
 public RecursiveDescentParser(Grammar g)
     : base(g)
 {
     ConstructPredictiveParseTable();
 }
예제 #13
0
 public Parser(Grammar grammar)
 {
     Grammar = grammar;
 }
예제 #14
0
 public static bool IsAcceptingState(this IEnumerable<Item> items, Grammar grammar)
 {
     return items
         .Where(a => a.Production.Head.Equals(grammar.Root))
         .Any(a => a.Position == a.Production.Body.Length);
 }
예제 #15
0
파일: SLR1.cs 프로젝트: martindevans/Hermes
 public SLR1(Grammar grammar)
     : base(grammar)
 {
 }
예제 #16
0
 private ParseState MakeStateState(NonTerminal root, Grammar g)
 {
     return new HashSet<Item>(root.Rules.Select(a => new Item(new Production(root, a), 0))).Closure(g);
 }
예제 #17
0
 public LRParserBase(Grammar g)
     : base(g)
 {
 }
예제 #18
0
파일: LR0.cs 프로젝트: martindevans/Hermes
 public LR0(Grammar grammar)
     : base(grammar)
 {
     automaton = CreateAutomaton(grammar);
 }