Ejemplo n.º 1
0
    private void computeClosure(HashSet <LR0Item> stateItems)
    {
        int            stateIndex = 0;
        List <LR0Item> toConsider = stateItems.ToList();

        while (stateIndex < toConsider.Count)
        {
            LR0Item item = toConsider[stateIndex];
            stateIndex++;
            if (!item.DposAtEnd())
            {
                string sym = item.Rhs[item.Dpos];
                if (productionDict.ContainsKey(sym)) //nonterminal
                {
                    foreach (string p in productionDict[sym].productions)
                    {
                        LR0Item item2 = new LR0Item(sym, getProductionAsList(p), 0);
                        if (!stateItems.Contains(item2))
                        {
                            stateItems.Add(item2);
                            toConsider.Add(item2);
                        }
                    }
                }
            }
        }
    }
    public override bool Equals(object obj)
    {
        if (obj == null)
        {
            return(false);
        }
        LR0Item o = obj as LR0Item;

        if (o == null ||
            o.Lhs != this.Lhs ||
            o.Dpos != this.Dpos ||
            o.Rhs.Count != this.Rhs.Count)
        {
            return(false);
        }

        for (int i = 0; i < this.Rhs.Count; i++)
        {
            if (o.Rhs[i] != this.Rhs[i])
            {
                return(false);
            }
        }
        return(true);
    }
 public LRItem FindByCore(LR0Item core)
 {
     foreach (LRItem item in this)
     {
         if (item.Core == core)
         {
             return(item);
         }
     }
     return(null);
 }
 private LRItem TryFindItem(ParserState state, LR0Item core)
 {
     foreach (LRItem item in state.Items)
     {
         if (item.Core == core)
         {
             return(item);
         }
     }
     return(null);
 }//method
 private static int ById(LR0Item x, LR0Item y)
 {
     if (x.ID < y.ID)
     {
         return(-1);
     }
     if (x.ID == y.ID)
     {
         return(0);
     }
     return(1);
 }
Ejemplo n.º 6
0
 private static int CompareLR0Items(LR0Item x, LR0Item y)
 {
     if (x.ID < y.ID)
     {
         return(-1);
     }
     if (x.ID == y.ID)
     {
         return(0);
     }
     return(1);
 }
Ejemplo n.º 7
0
        public bool IsAccepted(LR0State state)
        {
            if (state.Items.Count == 1)
            {
                var accItem = new LR0Item(augmentedGrammar.StartingSymbol, grammar.StartingSymbol + ".");
                if (accItem.Equals(state.Items[0]))
                {
                    return(true);
                }
            }

            return(false);
        }
        //Creates closure items with "spontaneously generated" lookaheads
        private bool AddClosureItems(ParserState state)
        {
            bool result = false;

            //note that we change collection while we iterate thru it, so we have to use "for i" loop
            for (int i = 0; i < state.Items.Count; i++)
            {
                LRItem  item     = state.Items[i];
                BnfTerm currTerm = item.Core.Current;
                if (currTerm == null || !(currTerm is NonTerminal))
                {
                    continue;
                }
                //1. Add normal closure items
                NtData currInfo = (NtData)currTerm.ParserData;
                foreach (Production prod in currInfo.Productions)
                {
                    LR0Item core    = prod.LR0Items[0]; //item at zero index is the one that starts with dot
                    LRItem  newItem = TryFindItem(state, core);
                    if (newItem == null)
                    {
                        newItem = new LRItem(state, core);
                        state.Items.Add(newItem);
                        result = true;
                    }
                    #region Comments on lookaheads processing
                    // The general idea of generating ("spontaneously") the lookaheads is the following:
                    // Let's the original item be in the form
                    //   [A -> alpha . B beta , lset]
                    //     where <B> is a non-terminal and <lset> is a set of lookaheads,
                    //      <beta> is some string (B's tail in our terminology)
                    // Then the closure item on non-teminal B is an item
                    //   [B -> x, firsts(beta + lset)]
                    //      (the lookahead set is expression after the comma).
                    // To generate lookaheads on a closure item, we simply take "firsts"
                    //   from the tail <beta> of the NonTerminal <B>.
                    //   Normally if tail <beta> is nullable we would add ("propagate")
                    //   the <lset> lookaheads from <A> to <B>.
                    //   We dont' do it right here - we simply add a propagation link.
                    //   We propagate all lookaheads later in a separate process.
                    #endregion
                    newItem.NewLookaheads.AddRange(item.Core.TailFirsts);
                    if (item.Core.TailIsNullable && !item.PropagateTargets.Contains(newItem))
                    {
                        item.PropagateTargets.Add(newItem);
                    }
                } //foreach prod
            }     //for i (LRItem)
            return(result);
        }
        }                     //method

        #endregion

        #region Calculating Tail Firsts
        private void CalculateTailFirsts()
        {
            foreach (NonTerminal nt in _grammar.NonTerminals)
            {
                foreach (Production prod in nt.Productions)
                {
                    StringSet accumulatedFirsts = new StringSet();
                    bool      allNullable       = true;
                    //We are going backwards in LR0Items list
                    for (int i = prod.LR0Items.Count - 1; i >= 0; i--)
                    {
                        LR0Item item = prod.LR0Items[i];
                        if (i >= prod.LR0Items.Count - 2)
                        {
                            //Last and before last items have empty tails
                            item.TailIsNullable = true;
                            item.TailFirsts.Clear();
                            continue;
                        }
                        BnfTerm nextTerm = prod.RValues[i + 1]; //Element after-after-dot; remember we're going in reverse direction
                        //if (ntElem == null) continue; //it is not NonTerminal
                        NonTerminal nextNt      = nextTerm as NonTerminal;
                        bool        notNullable = nextTerm is Terminal || nextNt != null && !nextNt.Nullable;
                        if (notNullable) //next term is not nullable  (a terminal or non-nullable NonTerminal)
                        //term is not nullable, so we clear all old firsts and add this term
                        {
                            accumulatedFirsts.Clear();
                            allNullable         = false;
                            item.TailIsNullable = false;
                            if (nextTerm is Terminal)
                            {
                                item.TailFirsts.Add(nextTerm.Key);//term is terminal so add its key
                                accumulatedFirsts.Add(nextTerm.Key);
                            }
                            else if (nextNt != null)                     //it is NonTerminal
                            {
                                item.TailFirsts.AddRange(nextNt.Firsts); //nonterminal
                                accumulatedFirsts.AddRange(nextNt.Firsts);
                            }
                            continue;
                        }
                        //if we are here, then ntElem is a nullable NonTerminal. We add
                        accumulatedFirsts.AddRange(nextNt.Firsts);
                        item.TailFirsts.AddRange(accumulatedFirsts);
                        item.TailIsNullable = allNullable;
                    } //for i
                }     //foreach prod
            }         //foreach nt
        }             //method
        private Production CreateProduction(NonTerminal lvalue, BnfTermList operands)
        {
            Production prod = new Production(lvalue);

            //create RValues list skipping Empty terminal and collecting grammar hints
            foreach (BnfTerm operand in operands)
            {
                if (operand == Grammar.Empty)
                {
                    continue;
                }
                //Collect hints as we go - they will be added to the next non-hint element
                GrammarHint hint = operand as GrammarHint;
                if (hint != null)
                {
                    hint.Position = prod.RValues.Count;
                    prod.Hints.Add(hint);
                    continue;
                }
                //Check if it is a Terminal or Error element
                Terminal t = operand as Terminal;
                if (t != null)
                {
                    prod.Flags |= ProductionFlags.HasTerminals;
                    if (t.Category == TokenCategory.Error)
                    {
                        prod.Flags |= ProductionFlags.IsError;
                    }
                }
                //Add the operand info and LR0 Item
                _itemID++;
                LR0Item item = new LR0Item(prod, prod.RValues.Count, _itemID);
                prod.LR0Items.Add(item);
                prod.RValues.Add(operand);
            }//foreach operand
            //set the flags
            if (lvalue == Data.AugmentedRoot)
            {
                prod.Flags |= ProductionFlags.IsInitial;
            }
            if (prod.RValues.Count == 0)
            {
                prod.Flags |= ProductionFlags.IsEmpty;
            }
            //Add final LRItem
            _itemID++;
            prod.LR0Items.Add(new LR0Item(prod, prod.RValues.Count, _itemID));
            return(prod);
        }
Ejemplo n.º 11
0
    public SLR_1_(Dictionary <string, Production> prodDict, List <Production> prods, HashSet <string> nulls, Dictionary <string, HashSet <string> > follow, List <Token> t, ref List <Dictionary <string, Tuple <string, int, string> > > LRTable, ref TreeNode productionTreeRoot, ref State startState, bool computeTree)
    {
        productions    = prods;
        productionDict = prodDict;
        nullables      = nulls;
        Follows        = follow;
        tokens         = t;

        //create Start State
        states     = new List <State>();
        startState = new State(0);
        LR0Item start = new LR0Item("S'", new List <string> {
            "program"
        }, 0);

        LRTable = new List <Dictionary <string, Tuple <string, int, string> > >();
        Dictionary <HashSet <LR0Item>, State> seen = new Dictionary <HashSet <LR0Item>, State>(new EQ());
        Stack <State> todo = new Stack <State>();

        startState.Items.Add(start);
        computeClosure(startState.Items);

        states.Add(startState);
        seen.Add(startState.Items, startState);
        todo.Push(startState);

        while (todo.Count > 0)
        {
            State Q = todo.Pop();
            Dictionary <string, HashSet <LR0Item> > transitions = computeTransitions(Q);
            addStates(Q, transitions, seen, todo);
        }

        //printSeenMap(seen);
        computeSLRTable(ref LRTable);
        //printLRTable(LRTable);
        //printTokens(t);
        //LRdot dot = new LRdot(startState, grammarFile);
        if (computeTree)
        {
            SLR_Parse(LRTable, ref productionTreeRoot);
        }
    }
Ejemplo n.º 12
0
    public GLR(Dictionary <string, Production> prodDict, string firstProduction, Dictionary <string, HashSet <string> > follow, List <Token> t, ref List <Dictionary <string, List <Tuple <string, int, string> > > > parseTable, ref TreeNode productionTreeRoot, ref State startState, bool computeTree)
    {
        productionDict = prodDict;
        Follows        = follow;
        tokens         = t;

        //create Start State
        states     = new List <State>();
        startState = new State(0);
        LR0Item start = new LR0Item("S'", new List <string> {
            firstProduction
        }, 0);

        parseTable = new List <Dictionary <string, List <Tuple <string, int, string> > > >();
        seen       = new Dictionary <HashSet <LR0Item>, State>(new EQ());
        Stack <State> todo = new Stack <State>();

        startState.Items.Add(start);
        computeClosure(startState.Items);

        states.Add(startState);
        seen.Add(startState.Items, startState);
        todo.Push(startState);

        while (todo.Count > 0)
        {
            State Q = todo.Pop();
            Dictionary <string, HashSet <LR0Item> > transitions = computeTransitions(Q);
            addStates(Q, transitions, seen, todo);
        }

        printSeenMap(seen);
        computeGLRTable(ref parseTable);
        printGLRTable(parseTable);
        printTokens(t);
        LRdot dot = new LRdot(startState, "gFile.dot");

        if (computeTree)
        {
            GLR_Parse(parseTable, ref productionTreeRoot);
        }
    }
        }//method

        private ShiftTable GetStateShifts(ParserState state)
        {
            ShiftTable  shifts = new ShiftTable();
            LR0ItemList list;

            foreach (LRItem item in state.Items)
            {
                BnfTerm term = item.Core.Current;
                if (term == null)
                {
                    continue;
                }
                LR0Item shiftedItem = item.Core.Production.LR0Items[item.Core.Position + 1];
                if (!shifts.TryGetValue(term.Key, out list))
                {
                    shifts[term.Key] = list = new LR0ItemList();
                }
                list.Add(shiftedItem);
            } //foreach
            return(shifts);
        }     //method
Ejemplo n.º 14
0
        public void DumpLR0Item(LR0Item item)
        {
            _builder.Append(_parser.Grammar.TokenCategories[_parser.Productions[item.Production].Left]);
            _builder.Append(" ->");
            int nPosition = 0;
            for (; ; )
            {
                if (nPosition == item.Position)
                {
                    _builder.Append(" *");
                }
                if (nPosition >= _parser.Productions[item.Production].Right.Length)
                {
                    break;
                }
                int nToken = _parser.Productions[item.Production].Right[nPosition];
                _builder.Append(" " + _parser.Grammar.TokenCategories[nToken]);

                nPosition++;
            }
        }
Ejemplo n.º 15
0
        public int ReduceTo(LR0State state)
        {
            var item = state.Items[0];

            var lhsItem = item.lhs;
            var rhsItem = item.rhs.Substring(0, item.rhs.Length - 1);
            var newItem = new LR0Item(lhsItem, rhsItem);

            var index = 0;

            foreach (var originalItem in grammar.ProductionList)
            {
                if (originalItem.Equals(newItem))
                {
                    return(index);
                }
                index++;
            }

            return(-1);
        }
Ejemplo n.º 16
0
    private Dictionary <string, HashSet <LR0Item> > computeTransitions(State State)
    {
        //make copy of transitions dictionary in State
        Dictionary <string, HashSet <LR0Item> > transitions = new Dictionary <string, HashSet <LR0Item> >();

        //add new transitions if not in dict
        foreach (LR0Item item in State.Items)
        {
            if (!item.DposAtEnd())
            {
                string sym = item.Rhs[item.Dpos];
                if (!transitions.ContainsKey(sym))
                {
                    transitions.Add(sym, new HashSet <LR0Item>());
                }
                LR0Item newItem = new LR0Item(item.Lhs, item.Rhs, item.Dpos + 1);
                //Console.WriteLine("adding production rhsLen:" + newItem.Rhs.Count + " " + newItem.ToString());
                transitions[sym].Add(newItem);
            }
        }
        //return copy as new Dict
        return(transitions);
    }
Ejemplo n.º 17
0
    //LR(0) stuff
    private void LR_Grammar_Proc()
    {
        //create Start State
        setTerminals();
        startState = new State();
        LR0Item start = new LR0Item("S'", new List <string> {
            "S"
        }, 0);
        Dictionary <HashSet <LR0Item>, State> seen = new Dictionary <HashSet <LR0Item>, State>(new EQ());
        Stack <State> todo = new Stack <State>();

        startState.Items.Add(start);
        computeClosure(startState.Items);
        seen.Add(startState.Items, startState);
        todo.Push(startState);

        while (todo.Count > 0)
        {
            State Q = todo.Pop();
            Dictionary <string, HashSet <LR0Item> > transitions = computeTransitions(Q);
            addStates(Q, transitions, seen, todo);
        }
    }
Ejemplo n.º 18
0
    //LR(0) stuff
    private void LR_Grammar_Proc()
    {
        //create Start State
        states     = new List <State>();
        startState = new State();
        LR0Item start = new LR0Item("S'", new List <string> {
            "S"
        }, 0);
        Dictionary <HashSet <LR0Item>, State> seen = new Dictionary <HashSet <LR0Item>, State>(new EQ());
        Stack <State> todo = new Stack <State>();


        startState.Items.Add(start);
        computeClosure(startState.Items);

        states.Add(startState);
        seen.Add(startState.Items, startState);
        todo.Push(startState);

        while (todo.Count > 0)
        {
            State Q = todo.Pop();
            Dictionary <string, HashSet <LR0Item> > transitions = computeTransitions(Q);
            addStates(Q, transitions, seen, todo);
        }

        computeSLRTable();

        printSeenMap(seen);
        printLRTable();
        LRdot dot = new LRdot(startState, grammarFile);

        if (this.inputFile != null)
        {
            SLR_Parse();
        }
    }
Ejemplo n.º 19
0
        /// <summary>
        /// takes a set of LR0 Items and Produces all of the LR0 Items that are reachable by substitution
        /// </summary>
        HashSet<int> LR0Closure(IEnumerable<int> items)
        {
            var closed = new HashSet<int>();
            var open = items.ToList();

            while (open.Count > 0)
            {
                int nItem = open[0];
                open.RemoveAt(0);
                LR0Item item = _lr0Items[nItem];
                closed.Add(nItem);

                int nProduction = 0;
                foreach (var production in _productions)
                {
                    if ((item.Position < _productions[item.Production].Right.Length) && (production.Left == _productions[item.Production].Right[item.Position]))
                    {
                        var newItem = new LR0Item(nProduction, 0);
                        int nNewItemID = GetLR0ItemID(newItem);
                        if (!open.Contains(nNewItemID) && !closed.Contains(nNewItemID))
                        {
                            open.Add(nNewItemID);

                        }
                    }
                    nProduction++;
                }
            }

            return closed;
        }
Ejemplo n.º 20
0
 private Production CreateProduction(NonTerminal lvalue, BnfTermList operands)
 {
     Production prod = new Production(lvalue);
       GrammarHintList hints = null;
       //create RValues list skipping Empty terminal and collecting grammar hints
       foreach (BnfTerm operand in operands) {
     if (operand == Grammar.CurrentGrammar.Empty)
       continue;
     //Collect hints as we go - they will be added to the next non-hint element
     GrammarHint hint = operand as GrammarHint;
     if (hint != null) {
       if (hints == null) hints = new GrammarHintList();
       hints.Add(hint);
       continue;
     }
     //Check if it is a Terminal or Error element
     Terminal t = operand as Terminal;
     if (t != null) {
       prod.Flags |= ProductionFlags.HasTerminals;
       if (t.Category == TokenCategory.Error) prod.Flags |= ProductionFlags.IsError;
     }
     //Add the operand info and LR0 Item
     LR0Item item = new LR0Item(_lastItemId++, prod, prod.RValues.Count, hints);
     prod.LR0Items.Add(item);
     prod.RValues.Add(operand);
     hints = null;
       }//foreach operand
       //set the flags
       if (prod.RValues.Count == 0)
     prod.Flags |= ProductionFlags.IsEmpty;
       //Add final LRItem
       prod.LR0Items.Add(new LR0Item(_lastItemId++, prod, prod.RValues.Count, hints));
       return prod;
 }
Ejemplo n.º 21
0
 public LRItem(ParserState state, LR0Item core)
 {
     State     = state;
     Core      = core;
     _hashCode = unchecked (state.GetHashCode() + core.GetHashCode());
 }
Ejemplo n.º 22
0
 /// <summary>
 /// takes an LR0 state, and a tokenID, and produces the next state given the token and productions of the grammar
 /// </summary>
 int GotoLR0(int nState, int nTokenID, ref bool bAdded, ref int nPrecedence)
 {
     var gotoLR0 = new HashSet<int>();
     var state = _lr0States[nState];
     foreach (int nItem in state)
     {
         LR0Item item = _lr0Items[nItem];
         if (item.Position < _productions[item.Production].Right.Length && (_productions[item.Production].Right[item.Position] == nTokenID))
         {
             var newItem = new LR0Item(item.Production, item.Position + 1);
             int nNewItemID = GetLR0ItemID(newItem);
             gotoLR0.Add(nNewItemID);
             int nProductionPrecedence = _productionPrecedence[item.Production];
             if (nPrecedence < nProductionPrecedence)
             {
                 nPrecedence = nProductionPrecedence;
             }
         }
     }
     return gotoLR0.Count == 0 ? -1 : GetLR0StateID(LR0Closure(gotoLR0), ref bAdded);
 }
Ejemplo n.º 23
0
 public LRItem(ParserState state, LR0Item core)
 {
     State = state;
     Core  = core;
 }
Ejemplo n.º 24
0
 /// <summary>
 /// Gets the ID for a particular LR0 Item
 /// </summary>
 int GetLR0ItemID(LR0Item item)
 {
     int nItemID = 0;
     foreach (LR0Item oItem in _lr0Items)
     {
         if (oItem.Equals(item))
         {
             return nItemID;
         }
         nItemID++;
     }
     _lr0Items.Add(item);
     return nItemID;
 }
Ejemplo n.º 25
0
        /// <summary>
        /// Initializes the propogation table, and initial state of the LALR table
        /// </summary>
        int InitLALRTables()
        {
            int nLR0State = 0;
            for (var i = 0; i < _lr0States.Count; i++ )
            {
                _lalrStates.Add(new HashSet<int>());
            }
            foreach (var lr0Kernel in _lr0Kernels)
            {
                var j = new HashSet<int>();
                foreach (int jLR0ItemID in lr0Kernel)
                {
                    var lr1Item = new LR1Item(jLR0ItemID, -1);
                    int nLR1ItemID = GetLR1ItemID(lr1Item);
                    j.Add(nLR1ItemID);
                }
                var jPrime = LR1Closure(j);
                foreach (int jpLR1ItemID in jPrime)
                {
                    var lr1Item = _lr1Items[jpLR1ItemID];
                    var lr0Item = _lr0Items[lr1Item.LR0ItemID];

                    if ((lr1Item.LookAhead != -1) || (nLR0State == 0))
                    {
                        _lalrStates[nLR0State].Add(jpLR1ItemID);
                    }

                    if (lr0Item.Position < _productions[lr0Item.Production].Right.Length)
                    {
                        int nToken = _productions[lr0Item.Production].Right[lr0Item.Position];
                        var lr0Successor = new LR0Item(lr0Item.Production, lr0Item.Position + 1);
                        int nLR0Successor = GetLR0ItemID(lr0Successor);
                        int nSuccessorState = _lrGotos[nLR0State][nToken];
                        if (lr1Item.LookAhead == -1)
                        {
                            AddPropogation(nLR0State, lr1Item.LR0ItemID, nSuccessorState, nLR0Successor);
                        }
                        else
                        {
                            var lalrItem = new LR1Item( nLR0Successor, lr1Item.LookAhead);
                            int nLALRItemID = GetLR1ItemID(lalrItem);
                            _lalrStates[nSuccessorState].Add(nLALRItemID);
                        }
                    }
                }

                nLR0State++;
            }
            return _lalrStates.Count;
        }
Ejemplo n.º 26
0
 private static int CompareLR0Items(LR0Item x, LR0Item y)
 {
     if (x.ID < y.ID) return -1;
       if (x.ID == y.ID) return 0;
       return 1;
 }
Ejemplo n.º 27
0
        /// <summary>
        /// takes a set of LR1 Items (LR0 items with lookaheads) and produces all of those LR1 items reachable by substitution
        /// </summary>
        HashSet<int> LR1Closure(IEnumerable<int> items)
        {
            var closed = new HashSet<int>();
            var open = items.ToList();

            while (open.Count > 0)
            {
                int nLR1Item = open[0];
                open.RemoveAt(0);
                LR1Item lr1Item = _lr1Items[nLR1Item];
                LR0Item lr0Item = _lr0Items[lr1Item.LR0ItemID];
                closed.Add(nLR1Item);

                if (lr0Item.Position < _productions[lr0Item.Production].Right.Length)
                {
                    int nToken = _productions[lr0Item.Production].Right[lr0Item.Position];
                    if (_nonterminals.Contains(nToken))
                    {
                        var argFirst = new List<int>();
                        for (int nIdx = lr0Item.Position + 1; nIdx < _productions[lr0Item.Production].Right.Length; nIdx++)
                        {
                            argFirst.Add(_productions[lr0Item.Production].Right[nIdx]);
                        }
                        var first = First(argFirst, lr1Item.LookAhead);
                        int nProduction = 0;
                        foreach (var production in _productions)
                        {
                            if (production.Left == nToken)
                            {
                                foreach (int nTokenFirst in first)
                                {
                                    var newLR0Item = new LR0Item(nProduction, 0);
                                    int nNewLR0ItemID = GetLR0ItemID(newLR0Item);
                                    var newLR1Item = new LR1Item(nNewLR0ItemID, nTokenFirst);
                                    int nNewLR1ItemID = GetLR1ItemID(newLR1Item);
                                    if (!open.Contains(nNewLR1ItemID) && !closed.Contains(nNewLR1ItemID))
                                    {
                                        open.Add(nNewLR1ItemID);
                                    }
                                }
                            }
                            nProduction++;
                        }
                    }
                }
            }

            return closed;
        }