private void PropagateLookaheads()
        {
            LRItemList currentList = new LRItemList();

            //first collect all items
            foreach (ParserState state in Data.States)
            {
                currentList.AddRange(state.Items);
            }
            //Main loop - propagate until done
            while (currentList.Count > 0)
            {
                LRItemList newList = new LRItemList();
                foreach (LRItem item in currentList)
                {
                    if (item.NewLookaheads.Count == 0)
                    {
                        continue;
                    }
                    int oldCount = item.Lookaheads.Count;
                    item.Lookaheads.AddRange(item.NewLookaheads);
                    if (item.Lookaheads.Count != oldCount)
                    {
                        foreach (LRItem targetItem in item.PropagateTargets)
                        {
                            targetItem.NewLookaheads.AddRange(item.NewLookaheads);
                            newList.Add(targetItem);
                        } //foreach targetItem
                    }     //if
                    item.NewLookaheads.Clear();
                }         //foreach item
                currentList = newList;
            }             //while
        }                 //method
Ejemplo n.º 2
0
        private void PropagateLookaheads()
        {
            LRItemList currentList = new LRItemList();

            _data.States.ForEach(state => currentList.AddRange(state.Items));

            while (currentList.Count > 0)
            {
                LRItemList newList = new LRItemList();

                foreach (LRItem item in currentList)
                {
                    if (item.NewLookaheads.Count == 0)
                    {
                        continue;
                    }

                    int oldCount = item.Lookaheads.Count;
                    item.Lookaheads.AddRange(item.NewLookaheads);

                    if (item.Lookaheads.Count != oldCount)
                    {
                        foreach (LRItem targetItem in item.PropagateTargets)
                        {
                            targetItem.NewLookaheads.AddRange(item.NewLookaheads);
                            newList.Add(targetItem);
                        }
                    }

                    item.NewLookaheads.Clear();
                }

                currentList = newList;
            }
        }
Ejemplo n.º 3
0
        }         //method

        private void ResolveConflictByHints(ParserState state, Terminal conflict)
        {
            var stateData = state.BuilderData;
            //reduce hints
            var reduceItems = stateData.ReduceItems.SelectByLookahead(conflict);

            foreach (var reduceItem in reduceItems)
            {
                if (reduceItem.Core.Hints.Find(h => h.HintType == HintType.ResolveToReduce) != null)
                {
                    state.Actions[conflict] = new ParserAction(ParserActionType.Reduce, null, reduceItem.Core.Production);
                    state.BuilderData.ResolvedConflicts.Add(conflict);
                    return;
                }
            }

            //Shift hints
            var shiftItems = stateData.ShiftItems.SelectByCurrent(conflict);

            foreach (var shiftItem in shiftItems)
            {
                if (shiftItem.Core.Hints.Find(h => h.HintType == HintType.ResolveToShift) != null)
                {
                    //shift action is already there
                    state.BuilderData.ResolvedConflicts.Add(conflict);
                    return;
                }
            }
            //code hints
            // first prepare data for conflict action: reduceProduction (for possible reduce) and newState (for possible shift)
            var         reduceProduction = reduceItems.First().Core.Production; //take first of reduce productions
            ParserState newState         = (state.Actions.ContainsKey(conflict) ? state.Actions[conflict].NewState : null);
            // Get all items that might contain hints;
            var allItems = new LRItemList();

            allItems.AddRange(state.BuilderData.ShiftItems.SelectByCurrent(conflict));
            allItems.AddRange(state.BuilderData.ReduceItems.SelectByLookahead(conflict));
            // Scan all items and try to find hint with resolution type Code
            foreach (var item in allItems)
            {
                if (item.Core.Hints.Find(h => h.HintType == HintType.ResolveInCode) != null)
                {
                    state.Actions[conflict] = new ParserAction(ParserActionType.Code, newState, reduceProduction);
                    state.BuilderData.ResolvedConflicts.Add(conflict);
                    return;
                }
            }
        }
Ejemplo n.º 4
0
        private bool TryResolveConflictByHints(ParserState state, BnfTerm conflict)
        {
            var stateData = state.BuilderData;
              //reduce hints
              var reduceItems = stateData.ReduceItems.SelectByLookahead(conflict);
              foreach(var reduceItem in reduceItems)
            if (reduceItem.Core.Hints != null)
              foreach (var hint in reduceItem.Core.Hints)
            if (hint.HintType == HintType.ResolveToReduce) {
              var newAction = ParserAction.CreateReduce(reduceItem.Core.Production);
              state.Actions[conflict] = newAction; //replace/add reduce action
              return true;
            }

              //Shift hints
              var shiftItems = stateData.ShiftItems.SelectByCurrent(conflict);
              foreach (var shiftItem in shiftItems)
            if (shiftItem.Core.Hints != null)
              foreach (var hint in shiftItem.Core.Hints)
            if (hint.HintType == HintType.ResolveToShift) {
              //shift action is already there
              return true;
            }

              //code hints
              // first prepare data for conflict action: reduceProduction (for possible reduce) and newState (for possible shift)
              var reduceProduction = reduceItems.First().Core.Production; //take first of reduce productions
              ParserState newState = (state.Actions.ContainsKey(conflict) ? state.Actions[conflict].NewState : null);
              // Get all items that might contain hints; first take all shift items and reduce items in conflict;
              // we should also add lookahead sources of reduce items. Lookahead source is an LR item that produces the lookahead,
              // so if it contains a code hint right before the lookahead term, then it applies to this conflict as well.
              var allItems = new LRItemList();
              allItems.AddRange(shiftItems);
              foreach (var reduceItem in reduceItems) {
            allItems.Add(reduceItem);
            allItems.AddRange(reduceItem.ReducedLookaheadSources);
              }
              // Scan all items and try to find hint with resolution type Code
              foreach (var item in allItems)
            if (item.Core.Hints != null)
              foreach (var hint in item.Core.Hints)
            if (hint.HintType == HintType.ResolveInCode) {
              //found hint with resolution type "code" - this is instruction to use custom code here to resolve the conflict
              // create new ConflictAction and place it into Actions table
              var newAction = ParserAction.CreateCodeAction(newState, reduceProduction);
              state.Actions[conflict] = newAction; //replace/add reduce action
              return true;
            }
              return false;
        }
Ejemplo n.º 5
0
        private void ResolveConflictByHints(ParserState state, Terminal conflict)
        {
            var stateData = state.BuilderData;
              //reduce hints
              var reduceItems = stateData.ReduceItems.SelectByLookahead(conflict);
              foreach(var reduceItem in reduceItems)
            if(reduceItem.Core.Hints.Find(h => h.HintType == HintType.ResolveToReduce) != null) {
              state.Actions[conflict] = new ParserAction(ParserActionType.Reduce, null, reduceItem.Core.Production);
              state.BuilderData.ResolvedConflicts.Add(conflict);
              return;
            }

              //Shift hints
              var shiftItems = stateData.ShiftItems.SelectByCurrent(conflict);
              foreach (var shiftItem in shiftItems)
            if(shiftItem.Core.Hints.Find(h => h.HintType == HintType.ResolveToShift) != null) {
              //shift action is already there
              state.BuilderData.ResolvedConflicts.Add(conflict);
              return;
            }
              //code hints
              // first prepare data for conflict action: reduceProduction (for possible reduce) and newState (for possible shift)
              var reduceProduction = reduceItems.First().Core.Production; //take first of reduce productions
              ParserState newState = (state.Actions.ContainsKey(conflict) ? state.Actions[conflict].NewState : null);
              // Get all items that might contain hints;
              var allItems = new LRItemList();
              allItems.AddRange(state.BuilderData.ShiftItems.SelectByCurrent(conflict));
              allItems.AddRange(state.BuilderData.ReduceItems.SelectByLookahead(conflict));
              // Scan all items and try to find hint with resolution type Code
              foreach (var item in allItems)
            if(item.Core.Hints.Find(h => h.HintType == HintType.ResolveInCode) != null) {
              state.Actions[conflict] = new ParserAction(ParserActionType.Code, newState, reduceProduction);
              state.BuilderData.ResolvedConflicts.Add(conflict);
              return;
            }
        }
Ejemplo n.º 6
0
        private bool TryResolveConflictByHints(ParserState state, BnfTerm conflict)
        {
            var stateData = state.BuilderData;
            //reduce hints
            var reduceItems = stateData.ReduceItems.SelectByLookahead(conflict);

            foreach (var reduceItem in reduceItems)
            {
                if (reduceItem.Core.Hints != null)
                {
                    foreach (var hint in reduceItem.Core.Hints)
                    {
                        if (hint.HintType == HintType.ResolveToReduce)
                        {
                            var newAction = ParserAction.CreateReduce(reduceItem.Core.Production);
                            state.Actions[conflict] = newAction; //replace/add reduce action
                            return(true);
                        }
                    }
                }
            }

            //Shift hints
            var shiftItems = stateData.ShiftItems.SelectByCurrent(conflict);

            foreach (var shiftItem in shiftItems)
            {
                if (shiftItem.Core.Hints != null)
                {
                    foreach (var hint in shiftItem.Core.Hints)
                    {
                        if (hint.HintType == HintType.ResolveToShift)
                        {
                            //shift action is already there
                            return(true);
                        }
                    }
                }
            }

            //code hints
            // first prepare data for conflict action: reduceProduction (for possible reduce) and newState (for possible shift)
            var         reduceProduction = reduceItems.First().Core.Production; //take first of reduce productions
            ParserState newState         = (state.Actions.ContainsKey(conflict) ? state.Actions[conflict].NewState : null);
            // Get all items that might contain hints; first take all shift items and reduce items in conflict;
            // we should also add lookahead sources of reduce items. Lookahead source is an LR item that produces the lookahead,
            // so if it contains a code hint right before the lookahead term, then it applies to this conflict as well.
            var allItems = new LRItemList();

            allItems.AddRange(shiftItems);
            foreach (var reduceItem in reduceItems)
            {
                allItems.Add(reduceItem);
                allItems.AddRange(reduceItem.ReducedLookaheadSources);
            }
            // Scan all items and try to find hint with resolution type Code
            foreach (var item in allItems)
            {
                if (item.Core.Hints != null)
                {
                    foreach (var hint in item.Core.Hints)
                    {
                        if (hint.HintType == HintType.ResolveInCode)
                        {
                            //found hint with resolution type "code" - this is instruction to use custom code here to resolve the conflict
                            // create new ConflictAction and place it into Actions table
                            var newAction = ParserAction.CreateCodeAction(newState, reduceProduction);
                            state.Actions[conflict] = newAction; //replace/add reduce action
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
Ejemplo n.º 7
0
    private void PropagateLookaheads()
    {
      LRItemList currentList = new LRItemList();
      _data.States.ForEach(state => currentList.AddRange(state.Items));

      while (currentList.Count > 0)
      {
        LRItemList newList = new LRItemList();
        
        foreach (LRItem item in currentList)
        {
          if (item.NewLookaheads.Count == 0) continue;
        
          int oldCount = item.Lookaheads.Count;
          item.Lookaheads.AddRange(item.NewLookaheads);
          
          if (item.Lookaheads.Count != oldCount)
          {
            foreach (LRItem targetItem in item.PropagateTargets)
            {
              targetItem.NewLookaheads.AddRange(item.NewLookaheads);
              newList.Add(targetItem);
            }
          }

          item.NewLookaheads.Clear();
        }

        currentList = newList;
      }
    }
Ejemplo n.º 8
0
    }//method

    private void ResolveConflictByHints(ParserState state, Terminal conflict) {
      var stateData = state.BuilderData;

      //reduce hints
      var reduceItems = stateData.ReduceItems.SelectByLookahead(conflict);
      foreach(var reduceItem in reduceItems)
        if(reduceItem.Core.Hints.Find(h => h.HintType == HintType.ResolveToReduce) != null) {
          state.Actions[conflict] = new ParserAction(ParserActionType.Reduce, null, reduceItem.Core.Production);
          state.BuilderData.ResolvedConflicts.Add(conflict);
          return; 
        }

      //shift hints
      var shiftItems = stateData.ShiftItems.SelectByCurrent(conflict);
      foreach (var shiftItem in shiftItems)
        if(shiftItem.Core.Hints.Find(h => h.HintType == HintType.ResolveToShift) != null) {
          //shift action is already there
          state.BuilderData.ResolvedConflicts.Add(conflict);
          return; 
        }

      //code hints
      // first prepare data for conflict action: reduceProduction (for possible reduce) and newState (for possible shift)
      var reduceProduction = reduceItems.First().Core.Production; //take first of reduce productions
      ParserState newState = (state.Actions.ContainsKey(conflict) ? state.Actions[conflict].NewState : null); 
      // Get all items that might contain hints;
      var allItems = new LRItemList();
      allItems.AddRange(state.BuilderData.ShiftItems.SelectByCurrent(conflict)); 
      allItems.AddRange(state.BuilderData.ReduceItems.SelectByLookahead(conflict)); 
      // Scan all items and try to find hint with resolution type Code
      foreach (var item in allItems) {
        if (item.Core.Hints.Find(h => h.HintType == HintType.ResolveInCode) != null) {
          state.Actions[conflict] = new ParserAction(ParserActionType.Code, newState, reduceProduction);
          state.BuilderData.ResolvedConflicts.Add(conflict);
          return; 
        }
      }

      //custom hints
      // find custom grammar hints and build custom conflict resolver
      var customHints = new List<CustomGrammarHint>();
      var hintItems = new Dictionary<CustomGrammarHint, LRItem>();
      LRItem defaultItem = null; // the first item with no hints
      foreach (var item in allItems) {
        var hints = item.Core.Hints.OfType<CustomGrammarHint>();
        foreach (var hint in hints) {
          customHints.Add(hint);
          hintItems[hint] = item;
        }
        if (defaultItem == null && !hints.Any())
          defaultItem = item;
      }
      // if there are custom hints, build conflict resolver
      if (customHints.Count > 0) {
        state.Actions[conflict] = new ParserAction(newState, reduceProduction, args => {
          // examine all custom hints and select the first production that matched
          foreach (var customHint in customHints) {
            if (customHint.Match(args)) {
              var item = hintItems[customHint];
              // If the ReduceProduction was clear, then use the default production following the hints
              if (args.ReduceProduction == null)
                args.ReduceProduction = item.Core.Production;
              return;
            }
          }
          // no hints matched, select default LRItem
          if (defaultItem != null) {
            args.ReduceProduction = defaultItem.Core.Production;
            args.Result = args.NewShiftState != null ? ParserActionType.Shift : ParserActionType.Reduce;
            return;
          }
          // prefer Reduce if Shift operation is not available
          args.Result = args.NewShiftState != null ? ParserActionType.Shift : ParserActionType.Reduce;
          // TODO: figure out what to do next
        });
        state.BuilderData.ResolvedConflicts.Add(conflict);
        return;
      }
    }
Ejemplo n.º 9
0
        }         //method

        private void ResolveConflictByHints(ParserState state, Terminal conflict)
        {
            var stateData = state.BuilderData;

            //reduce hints
            var reduceItems = stateData.ReduceItems.SelectByLookahead(conflict);

            foreach (var reduceItem in reduceItems)
            {
                if (reduceItem.Core.Hints.Find(h => h.HintType == HintType.ResolveToReduce) != null)
                {
                    state.Actions[conflict] = new ParserAction(ParserActionType.Reduce, null, reduceItem.Core.Production);
                    state.BuilderData.ResolvedConflicts.Add(conflict);
                    return;
                }
            }

            //shift hints
            var shiftItems = stateData.ShiftItems.SelectByCurrent(conflict);

            foreach (var shiftItem in shiftItems)
            {
                if (shiftItem.Core.Hints.Find(h => h.HintType == HintType.ResolveToShift) != null)
                {
                    //shift action is already there
                    state.BuilderData.ResolvedConflicts.Add(conflict);
                    return;
                }
            }

            //code hints
            // first prepare data for conflict action: reduceProduction (for possible reduce) and newState (for possible shift)
            var         reduceProduction = reduceItems.First().Core.Production; //take first of reduce productions
            ParserState newState         = (state.Actions.ContainsKey(conflict) ? state.Actions[conflict].NewState : null);
            // Get all items that might contain hints;
            var allItems = new LRItemList();

            allItems.AddRange(state.BuilderData.ShiftItems.SelectByCurrent(conflict));
            allItems.AddRange(state.BuilderData.ReduceItems.SelectByLookahead(conflict));
            // Scan all items and try to find hint with resolution type Code
            foreach (var item in allItems)
            {
                if (item.Core.Hints.Find(h => h.HintType == HintType.ResolveInCode) != null)
                {
                    state.Actions[conflict] = new ParserAction(ParserActionType.Code, newState, reduceProduction);
                    state.BuilderData.ResolvedConflicts.Add(conflict);
                    return;
                }
            }

            //custom hints
            // find custom grammar hints and build custom conflict resolver
            var    customHints = new List <CustomGrammarHint>();
            var    hintItems   = new Dictionary <CustomGrammarHint, LRItem>();
            LRItem defaultItem = null; // the first item with no hints

            foreach (var item in allItems)
            {
                var hints = item.Core.Hints.OfType <CustomGrammarHint>();
                foreach (var hint in hints)
                {
                    customHints.Add(hint);
                    hintItems[hint] = item;
                }
                if (defaultItem == null && !hints.Any())
                {
                    defaultItem = item;
                }
            }
            // if there are custom hints, build conflict resolver
            if (customHints.Count > 0)
            {
                state.Actions[conflict] = new ParserAction(newState, reduceProduction, args => {
                    // examine all custom hints and select the first production that matched
                    foreach (var customHint in customHints)
                    {
                        if (customHint.Match(args))
                        {
                            var item = hintItems[customHint];
                            args.ReduceProduction = item.Core.Production;
                            args.Result           = customHint.Action;
                            return;
                        }
                    }
                    // no hints matched, select default LRItem
                    if (defaultItem != null)
                    {
                        args.ReduceProduction = defaultItem.Core.Production;
                        args.Result           = args.NewShiftState != null ? ParserActionType.Shift : ParserActionType.Reduce;
                        return;
                    }
                    // prefer Reduce if Shift operation is not available
                    args.Result = args.NewShiftState != null ? ParserActionType.Shift : ParserActionType.Reduce;
                    // TODO: figure out what to do next
                });
                state.BuilderData.ResolvedConflicts.Add(conflict);
                return;
            }
        }