示例#1
0
 private ParserState CreateInitialState(NonTerminal augmentedRoot) {
   //for an augmented root there is an initial production "Root' -> .Root"; so we need the LR0 item at 0 index
   var iniItemSet = new LR0ItemSet();
   iniItemSet.Add(augmentedRoot.Productions[0].LR0Items[0]);
   var initialState = FindOrCreateState(iniItemSet);
   var rootNt = augmentedRoot.Productions[0].RValues[0] as NonTerminal; 
   Data.InitialStates[rootNt] = initialState; 
   return initialState;
 }
示例#2
0
        private ParserState CreateInitialState(NonTerminal augmentedRoot)
        {
            //for an augmented root there is an initial production "Root' -> .Root"; so we need the LR0 item at 0 index
            var iniItemSet = new LR0ItemSet();

            iniItemSet.Add(augmentedRoot.Productions[0].LR0Items[0]);
            var initialState = FindOrCreateState(iniItemSet);
            var rootNt       = augmentedRoot.Productions[0].RValues[0] as NonTerminal;

            _data.InitialStates[rootNt] = initialState;
            return(initialState);
        }
示例#3
0
        private TransitionList  CreateLookbackTransitions(LRItemSet sourceItems)
        {
            var newTransitions = new TransitionList();
            //Build set of initial cores - this is optimization for performance
            //We need to find all initial items in all states that shift into one of sourceItems
            // Each such initial item would have the core from the "initial" cores set that we build from source items.
            var iniCores = new LR0ItemSet();

            foreach (var sourceItem in sourceItems)
            {
                iniCores.Add(sourceItem.Core.Production.LR0Items[0]);
            }
            //find
            foreach (var state in Data.States)
            {
                foreach (var iniItem in state.BuilderData.InitialItems)
                {
                    if (!iniCores.Contains(iniItem.Core))
                    {
                        continue;
                    }
                    var currItem = iniItem;
                    while (currItem != null)
                    {
                        if (sourceItems.Contains(currItem))
                        {
                            //iniItem is initial item for currItem (one of source items)
                            // check if transition for iniItem's non-terminal exists
                            var        ntLeft = iniItem.Core.Production.LValue;
                            Transition trans;
                            if (!state.BuilderData.Transitions.TryGetValue(ntLeft, out trans))
                            {
                                trans = new Transition(iniItem.State, iniItem.Core.Production.LValue);
                                newTransitions.Add(trans);
                            }
                            //Now for currItem, either add trans to Lookbackbacks, or "include" it into currItem.Transition
                            if (currItem.Core.IsFinal)
                            {
                                currItem.Lookbacks.Add(trans);
                            }
                            else if (currItem.Transition != null)
                            {
                                currItem.Transition.Include(trans);
                            }
                        }//if
                        //move to next items
                        currItem = currItem.ShiftedItem;
                    } //while
                }     //foreach iniItem
            }         //foreach state
            return(newTransitions);
        }
示例#4
0
        public LR0ItemSet GetShiftedCores()
        {
            var result = new LR0ItemSet();

            foreach (var item in this)
            {
                if (item.Core.ShiftedItem != null)
                {
                    result.Add(item.Core.ShiftedItem);
                }
            }
            return(result);
        }
示例#5
0
        }             //method

        private ParserState FindOrCreateState(LR0ItemSet coreItems)
        {
            string      key = ComputeLR0ItemSetKey(coreItems);
            ParserState state;

            if (_stateHash.TryGetValue(key, out state))
            {
                return(state);
            }
            //create new state
            state             = new ParserState("S" + _data.States.Count);
            state.BuilderData = new ParserStateData(state, coreItems);
            _data.States.Add(state);
            _stateHash[key] = state;
            return(state);
        }
示例#6
0
        }//method

        /* Detecting conflicts that cannot be resolved by tail wrapping
         *   1. Shift-reduce conflicts. If inadequate state S has shift item based on the same core as source
         *       of one of reduced lookaheads of reduce item, then the conflict is unresolvable -
         *       no wrapping of lookahead would resolve ambiguity
         *   2. Reduce-reduce conflict. If reduce items in inadequate state have reduced lookaheads
         *      with sources having the same core (LR0 item) then we have unresolvable conflict. Wrapping of the item tail would produce
         *      the same new non-terminal as lookahead in both conflicting reduce items.
         */
        private void DetectConflictsUnresolvableByRestructuring(ParserState state)
        {
            //compute R-R and S-R conflicting lookaheads
            var rrConflicts     = new BnfTermSet();
            var srConflicts     = new BnfTermSet();
            var conflictSources = new LR0ItemSet();

            foreach (var conflict in state.BuilderData.Conflicts)
            {
                var nonConflictingSourceCores = new LR0ItemSet();
                foreach (var reduceItem in state.BuilderData.ReduceItems)
                {
                    foreach (var source in reduceItem.ReducedLookaheadSources)
                    {
                        if (source.Core.Current != conflict)
                        {
                            continue;
                        }
                        if (state.BuilderData.Cores.Contains(source.Core)) //we have unresolvable shift-reduce
                        {
                            srConflicts.Add(source.Core.Current);
                            conflictSources.Add(source.Core);
                        }
                        else if (nonConflictingSourceCores.Contains(source.Core)) //unresolvable reduce-reduce
                        {
                            rrConflicts.Add(source.Core.Current);
                            conflictSources.Add(source.Core);
                        }
                        else
                        {
                            nonConflictingSourceCores.Add(source.Core);
                        }
                    } //foreach source
                }     //foreach item
            }         //foreach conflict
            if (srConflicts.Count > 0)
            {
                ReportParseConflicts("Ambiguous grammar, unresolvable shift-reduce conflicts.", state, srConflicts);
            }
            if (rrConflicts.Count > 0)
            {
                ReportParseConflicts("Ambiguous grammar, unresolvable reduce-reduce conflicts.", state, rrConflicts);
            }
            //create default actions and remove them from conflict list, so we don't deal with them anymore
            CreateDefaultActionsForConflicts(state, srConflicts, rrConflicts);
        } // method
示例#7
0
 //Parser states are distinguished by the subset of kernel LR0 items.
 // So when we derive new LR0-item list by shift operation,
 // we need to find out if we have already a state with the same LR0Item list.
 // We do it by looking up in a state hash by a key - [LR0 item list key].
 // Each list's key is a concatenation of items' IDs separated by ','.
 // Before producing the key for a list, the list must be sorted;
 //   thus we garantee one-to-one correspondence between LR0Item sets and keys.
 // And of course, we count only kernel items (with dot NOT in the first position).
 public static string ComputeLR0ItemSetKey(LR0ItemSet items)
 {
     if (items.Count == 0) return string.Empty;
       //Copy non-initial items to separate list, and then sort it
       LR0ItemList itemList = new LR0ItemList();
       itemList.AddRange(items);
       //quick shortcut
       if (itemList.Count == 1)
     return itemList[0].ID.ToString();
       itemList.Sort(CompareLR0Items); //Sort by ID
       //now build the key
       StringBuilder sb = new StringBuilder(100);
       foreach (LR0Item item in itemList) {
     sb.Append(item.ID);
     sb.Append(",");
       }//foreach
       return sb.ToString();
 }
示例#8
0
 private ParserState CreateState(LR0ItemSet coreItems, string statePrefix)
 {
     string key = ComputeLR0ItemSetKey(coreItems);
       return CreateState(coreItems, key, statePrefix);
 }
示例#9
0
 private void CreateInitialState()
 {
     //there is always just one initial production "Root' -> .Root", and we're interested in LR item at 0 index
       var iniItemSet = new LR0ItemSet();
       iniItemSet.Add(_language.GrammarData.AugmentedRoot.Productions[0].LR0Items[0]);
       Data.InitialState = CreateState(iniItemSet, "S");
 }
    /*
    Initial condition: we have state S with conflicts on lookaheads in Sc.Conflicts. 
     Each reduce item Ir in S has a set of lookahead sources Ir.ReducedLookaheadSources. 
     Our goal is to a create non-canonical state ncState with proper lookaheds, create jumps to this state 
     on jump lookaheads from S to ncState, remove these jump lookaheads from lookahead sets of reduce items 
     and replace them with non-canonical non-terminal lookaheads.
    1. Compute all jump lookaheads jL and non-canonical lookaheads ncL for state Sc. 
    2. Collect relevant lookahead sources in lkhSources set. For each lookahead source lkhSrc in all reduce items, 
       if lkhSrc.Current.Firsts includes a jump lookahead in jL, include it into lkhSources. 
    3. Collect item cores for non-canonical state into ncCores. For each production Prod in productions 
       of current non-terminal of all items in lkhSources, if Prod.Firsts contains a jump lookahead, then add initial LR0 item of Prod 
       to ncCores.
    4. Add to ncCores all shift items in state Sc that have Current term in jump lookaheads. We need to include 
       such shift items from original state into non-canonical state to allow proper resolution of shift-reduce
       conflicts. We let shift items in current state "compete" with possible reductions to non-canonical lookaheads 
       inside non-canonical state. 
    5. Create (or find existing) non-canonical state Sn from ncCores. 
    6. Assign lookbacks to items in ncState. For each item Src in lkhSources, for each production Prod 
       in Src.Current.Productions, if Prod.DirectFirsts contains jump lookahead, then: 
       find LR item I in Sn with I.Core == Prod.LR0Items[0]; do the following: I.Lookbacks.Add(Src.Transition).
    7. For state S for each reduce item I adjust I.Lookaheads:  remove jump lookaheads from I.Lookaheads, 
         and add those non-canonical lookaheads that are in I.AllLookaheads
*/
    //TODO: one thing to look at - see if all items in ncState should lead to reduce item in some state. 
    //     There may be items (most likely top ones, expansions of original reduced lookahead) that never get 
    //     to full reduce, because we switch back to canonical state on reduction of some "child" non-terminal and
    //     continue through canonical states from there. 
    //     So we don't need to generate target transition states for these items (unreachable states). 
    //     The main trouble is that unreachable state may introduce conflicts that in fact are never realized. 
    #endregion
    private void SwitchStateToNLalrLookaheads(ParserState state) {
      //1. Compute minimal (most expanded) non-canonical lookaheads that resolve all conflicts
      ComputeStateNonCanonicalLookaheads(state);
      var stateData = state.BuilderData;
      //2. Collect reduced lookahead sources and non-terminal lookaheads
      var lkhSources = new LRItemSet();
      var ntSet = new NonTerminalSet(); //All non-terminals in current positions of lkhSources
      foreach(var reduceItem in stateData.ReduceItems)
        foreach (var lkhSource in reduceItem.ReducedLookaheadSources) {
          var ntLkh = lkhSource.Core.Current as NonTerminal;
          if (ntLkh == null) continue; 
          if (!ntLkh.Firsts.Overlaps(stateData.JumpLookaheads))continue;
          lkhSources.Add(lkhSource);
          ntSet.Add(ntLkh); 
        }
      //2. Collect core set for non-canonical state
      var ncCoreSet = new LR0ItemSet();
      foreach(var ntLkh in ntSet) 
        foreach(var prod in ntLkh.Productions)
          if (prod.Firsts.Overlaps(stateData.JumpLookaheads))
            ncCoreSet.Add(prod.LR0Items[0]); 
      //4. Add shift items
      foreach (var shiftItem in stateData.ShiftItems)
        if (stateData.JumpLookaheads.Contains(shiftItem.Core.Current))
          ncCoreSet.Add(shiftItem.Core); 
      //5. Find or create non-canonical state
      var oldStateCount = Data.States.Count;
      var ncState = FindOrCreateState(ncCoreSet, "SN"); //if not found, state is created and added to state list and state hash
      bool ncStateIsNew = Data.States.Count > oldStateCount;
      stateData.JumpTarget = ncState; 
      //6. Setup appropriate lookbacks in items in ncState; 
      // first set lookbacks for items originated from lookaheads of reduce items in original state.
      foreach(var lkhSource in lkhSources) {
        var ntLkh = lkhSource.Core.Current as NonTerminal;
        foreach (var prod in ntLkh.Productions)
          if (prod.Firsts.Overlaps(stateData.JumpLookaheads)) {
            var ncItem = ncState.BuilderData.AllItems.FindByCore(prod.LR0Items[0]);
            ncItem.Lookbacks.Add(lkhSource.Transition);
          }//if 
      }//foreach lkhSource
      //Now items orginated from shift items in original state in step 4 above
      // just copy lookbacks
      foreach (var shiftItem in stateData.ShiftItems)
        if (stateData.JumpLookaheads.Contains(shiftItem.Core.Current)) {
          var ncItem = ncState.BuilderData.ShiftItems.FindByCore(shiftItem.Core);
          shiftItem.ShiftedItem = ncItem; 
          ncItem.Lookbacks.UnionWith(shiftItem.Lookbacks);
          if (ncItem.Transition != null)
          ncItem.Transition.Include(shiftItem.Transition.Includes);
        }
      PropagateLookbacksAndTransitionsThruShifts(ncState); 
      //7. Adjust reduce items lookaheads in original state
      foreach (var reduceItem in stateData.ReduceItems) {
        foreach(var jumpLkh in stateData.JumpLookaheads)
          if (reduceItem.Lookaheads.Contains(jumpLkh))
            reduceItem.Lookaheads.Remove(jumpLkh);
        foreach (var ncLkh in stateData.NonCanonicalLookaheads)
          if (reduceItem.AllLookaheads.Contains(ncLkh))
            reduceItem.Lookaheads.Add(ncLkh);
      }//foreach reduceItem
      // 8. Create jump action to non-canonical state, remove shifts on jump lookaheads
      state.JumpAction = ParserAction.CreateJump(ncState);
      foreach (var jumpTerm in state.BuilderData.JumpLookaheads)
        if (state.Actions.ContainsKey(jumpTerm))
          state.Actions.Remove(jumpTerm); 
      //9. Complete generating states
      state.BuilderData.Conflicts.ExceptWith(state.BuilderData.JumpLookaheads);
    }//method
    }//method

    /* Detecting conflicts that cannot be resolved by tail wrapping 
         1. Shift-reduce conflicts. If inadequate state S has shift item based on the same core as source 
             of one of reduced lookaheads of reduce item, then the conflict is unresolvable - 
             no wrapping of lookahead would resolve ambiguity
         2. Reduce-reduce conflict. If reduce items in inadequate state have reduced lookaheads 
            with sources having the same core (LR0 item) then we have unresolvable conflict. Wrapping of the item tail would produce
            the same new non-terminal as lookahead in both conflicting reduce items. 
    */
    private void DetectConflictsUnresolvableByRestructuring(ParserState state) {
      //compute R-R and S-R conflicting lookaheads
      var rrConflicts = new BnfTermSet();
      var srConflicts = new BnfTermSet();
      var conflictSources = new LR0ItemSet();
      foreach (var conflict in state.BuilderData.Conflicts) {
        var nonConflictingSourceCores = new LR0ItemSet();
        foreach (var reduceItem in state.BuilderData.ReduceItems) {
          foreach (var source in reduceItem.ReducedLookaheadSources) {
            if (source.Core.Current != conflict) continue;
            if (state.BuilderData.Cores.Contains(source.Core)) {  //we have unresolvable shift-reduce
              srConflicts.Add(source.Core.Current);
              conflictSources.Add(source.Core);
            } else if (nonConflictingSourceCores.Contains(source.Core)) {        //unresolvable reduce-reduce
              rrConflicts.Add(source.Core.Current);
              conflictSources.Add(source.Core);
            } else
              nonConflictingSourceCores.Add(source.Core);
          }//foreach source
        }//foreach item
      }//foreach conflict
      if (srConflicts.Count > 0)
        ReportParseConflicts("Ambiguous grammar, unresolvable shift-reduce conflicts.", state, srConflicts);
      if (rrConflicts.Count > 0)
        ReportParseConflicts("Ambiguous grammar, unresolvable reduce-reduce conflicts.", state, rrConflicts);
      //create default actions and remove them from conflict list, so we don't deal with them anymore
      CreateDefaultActionsForConflicts(state, srConflicts, rrConflicts); 
    } // method
示例#12
0
 private ParserState FindOrCreateState(LR0ItemSet coreItems)
 {
     string key = ComputeLR0ItemSetKey(coreItems);
       ParserState state;
       if (_stateHash.TryGetValue(key, out state))
     return state;
       //create new state
       state = new ParserState("S" + Data.States.Count);
       state.BuilderData = new ParserStateData(state, coreItems);
       Data.States.Add(state);
       _stateHash[key] = state;
       return state;
 }
        private ParserState CreateState(LR0ItemSet coreItems, string statePrefix)
        {
            string key = ComputeLR0ItemSetKey(coreItems);

            return(CreateState(coreItems, key, statePrefix));
        }
示例#14
0
        /*
         * Initial condition: we have state S with conflicts on lookaheads in Sc.Conflicts.
         * Each reduce item Ir in S has a set of lookahead sources Ir.ReducedLookaheadSources.
         * Our goal is to a create non-canonical state ncState with proper lookaheds, create jumps to this state
         * on jump lookaheads from S to ncState, remove these jump lookaheads from lookahead sets of reduce items
         * and replace them with non-canonical non-terminal lookaheads.
         * 1. Compute all jump lookaheads jL and non-canonical lookaheads ncL for state Sc.
         * 2. Collect relevant lookahead sources in lkhSources set. For each lookahead source lkhSrc in all reduce items,
         * if lkhSrc.Current.Firsts includes a jump lookahead in jL, include it into lkhSources.
         * 3. Collect item cores for non-canonical state into ncCores. For each production Prod in productions
         * of current non-terminal of all items in lkhSources, if Prod.Firsts contains a jump lookahead, then add initial LR0 item of Prod
         * to ncCores.
         * 4. Add to ncCores all shift items in state Sc that have Current term in jump lookaheads. We need to include
         * such shift items from original state into non-canonical state to allow proper resolution of shift-reduce
         * conflicts. We let shift items in current state "compete" with possible reductions to non-canonical lookaheads
         * inside non-canonical state.
         * 5. Create (or find existing) non-canonical state Sn from ncCores.
         * 6. Assign lookbacks to items in ncState. For each item Src in lkhSources, for each production Prod
         * in Src.Current.Productions, if Prod.DirectFirsts contains jump lookahead, then:
         * find LR item I in Sn with I.Core == Prod.LR0Items[0]; do the following: I.Lookbacks.Add(Src.Transition).
         * 7. For state S for each reduce item I adjust I.Lookaheads:  remove jump lookaheads from I.Lookaheads,
         *   and add those non-canonical lookaheads that are in I.AllLookaheads
         */
        //TODO: one thing to look at - see if all items in ncState should lead to reduce item in some state.
        //     There may be items (most likely top ones, expansions of original reduced lookahead) that never get
        //     to full reduce, because we switch back to canonical state on reduction of some "child" non-terminal and
        //     continue through canonical states from there.
        //     So we don't need to generate target transition states for these items (unreachable states).
        //     The main trouble is that unreachable state may introduce conflicts that in fact are never realized.
        #endregion
        private void SwitchStateToNLalrLookaheads(ParserState state)
        {
            //1. Compute minimal (most expanded) non-canonical lookaheads that resolve all conflicts
            ComputeStateNonCanonicalLookaheads(state);
            var stateData = state.BuilderData;
            //2. Collect reduced lookahead sources and non-terminal lookaheads
            var lkhSources = new LRItemSet();
            var ntSet      = new NonTerminalSet(); //All non-terminals in current positions of lkhSources

            foreach (var reduceItem in stateData.ReduceItems)
            {
                foreach (var lkhSource in reduceItem.ReducedLookaheadSources)
                {
                    var ntLkh = lkhSource.Core.Current as NonTerminal;
                    if (ntLkh == null)
                    {
                        continue;
                    }
                    if (!ntLkh.Firsts.Overlaps(stateData.JumpLookaheads))
                    {
                        continue;
                    }
                    lkhSources.Add(lkhSource);
                    ntSet.Add(ntLkh);
                }
            }
            //2. Collect core set for non-canonical state
            var ncCoreSet = new LR0ItemSet();

            foreach (var ntLkh in ntSet)
            {
                foreach (var prod in ntLkh.Productions)
                {
                    if (prod.Firsts.Overlaps(stateData.JumpLookaheads))
                    {
                        ncCoreSet.Add(prod.LR0Items[0]);
                    }
                }
            }
            //4. Add shift items
            foreach (var shiftItem in stateData.ShiftItems)
            {
                if (stateData.JumpLookaheads.Contains(shiftItem.Core.Current))
                {
                    ncCoreSet.Add(shiftItem.Core);
                }
            }
            //5. Find or create non-canonical state
            var  oldStateCount = Data.States.Count;
            var  ncState       = FindOrCreateState(ncCoreSet, "SN"); //if not found, state is created and added to state list and state hash
            bool ncStateIsNew  = Data.States.Count > oldStateCount;

            stateData.JumpTarget = ncState;
            //6. Setup appropriate lookbacks in items in ncState;
            // first set lookbacks for items originated from lookaheads of reduce items in original state.
            foreach (var lkhSource in lkhSources)
            {
                var ntLkh = lkhSource.Core.Current as NonTerminal;
                foreach (var prod in ntLkh.Productions)
                {
                    if (prod.Firsts.Overlaps(stateData.JumpLookaheads))
                    {
                        var ncItem = ncState.BuilderData.AllItems.FindByCore(prod.LR0Items[0]);
                        ncItem.Lookbacks.Add(lkhSource.Transition);
                    } //if
                }
            }         //foreach lkhSource
            //Now items orginated from shift items in original state in step 4 above
            // just copy lookbacks
            foreach (var shiftItem in stateData.ShiftItems)
            {
                if (stateData.JumpLookaheads.Contains(shiftItem.Core.Current))
                {
                    var ncItem = ncState.BuilderData.ShiftItems.FindByCore(shiftItem.Core);
                    shiftItem.ShiftedItem = ncItem;
                    ncItem.Lookbacks.UnionWith(shiftItem.Lookbacks);
                    if (ncItem.Transition != null)
                    {
                        ncItem.Transition.Include(shiftItem.Transition.Includes);
                    }
                }
            }
            PropagateLookbacksAndTransitionsThruShifts(ncState);
            //7. Adjust reduce items lookaheads in original state
            foreach (var reduceItem in stateData.ReduceItems)
            {
                foreach (var jumpLkh in stateData.JumpLookaheads)
                {
                    if (reduceItem.Lookaheads.Contains(jumpLkh))
                    {
                        reduceItem.Lookaheads.Remove(jumpLkh);
                    }
                }
                foreach (var ncLkh in stateData.NonCanonicalLookaheads)
                {
                    if (reduceItem.AllLookaheads.Contains(ncLkh))
                    {
                        reduceItem.Lookaheads.Add(ncLkh);
                    }
                }
            }//foreach reduceItem
            // 8. Create jump action to non-canonical state, remove shifts on jump lookaheads
            state.JumpAction = ParserAction.CreateJump(ncState);
            foreach (var jumpTerm in state.BuilderData.JumpLookaheads)
            {
                if (state.Actions.ContainsKey(jumpTerm))
                {
                    state.Actions.Remove(jumpTerm);
                }
            }
            //9. Complete generating states
            state.BuilderData.Conflicts.ExceptWith(state.BuilderData.JumpLookaheads);
        }//method
示例#15
0
 private TransitionList  CreateLookbackTransitions(LRItemSet sourceItems) {
   var newTransitions = new TransitionList();
   //Build set of initial cores - this is optimization for performance
   //We need to find all initial items in all states that shift into one of sourceItems
   // Each such initial item would have the core from the "initial" cores set that we build from source items.
   var iniCores = new LR0ItemSet();
   foreach(var sourceItem in sourceItems)
     iniCores.Add(sourceItem.Core.Production.LR0Items[0]);
   //find 
   foreach(var state in Data.States) {
     foreach(var iniItem in state.BuilderData.InitialItems) {
       if (!iniCores.Contains(iniItem.Core)) continue; 
       var currItem = iniItem;
       while(currItem != null) {
         if(sourceItems.Contains(currItem)) {
           //iniItem is initial item for currItem (one of source items) 
           // check if transition for iniItem's non-terminal exists
           var ntLeft = iniItem.Core.Production.LValue;
           Transition trans; 
           if(!state.BuilderData.Transitions.TryGetValue(ntLeft, out trans)) {
             trans = new Transition(iniItem.State, iniItem.Core.Production.LValue);
             newTransitions.Add(trans);
           }
           //Now for currItem, either add trans to Lookbackbacks, or "include" it into currItem.Transition
           if(currItem.Core.IsFinal)
             currItem.Lookbacks.Add(trans);
           else if(currItem.Transition != null)
             currItem.Transition.Include(trans);
         }//if 
         //move to next items
         currItem = currItem.ShiftedItem;
       }//while
     }//foreach iniItem
   }//foreach state
   return newTransitions;
 }
示例#16
0
 private ParserState CreateState(LR0ItemSet coreItems, string key, string statePrefix)
 {
     var result = new ParserState(statePrefix + Data.States.Count);
       result.BuilderData = new ParserStateData(result, coreItems, key);
       Data.States.Add(result);
       _stateHash[key] = result;
       return result;
 }
示例#17
0
 private ParserState FindOrCreateState(LR0ItemSet coreItems, string statePrefix)
 {
     string key = ComputeLR0ItemSetKey(coreItems);
       ParserState result;
       if (_stateHash.TryGetValue(key, out result))
     return result;
       return CreateState(coreItems, key, statePrefix);
 }
示例#18
0
 private TransitionList CreateLookbackTransitions(LRItemSet sourceItems)
 {
     var newTransitions = new TransitionList();
       //Build set of initial cores - this is optimization for performance
       //We need to find all initial items in all states that shift into one of sourceItems
       // Each such initial item would have the core from the "initial" cores set that we build from source items.
       var iniCores = new LR0ItemSet();
       foreach(var sourceItem in sourceItems)
     iniCores.Add(sourceItem.Core.Production.LR0Items[0]);
       //find
       foreach(var state in Data.States) {
     foreach(var iniItem in state.BuilderData.InitialItems) {
       if (!iniCores.Contains(iniItem.Core)) continue;
       var iniItemNt = iniItem.Core.Production.LValue; // iniItem's non-terminal (left side of production)
       Transition lookback = null; // local var for lookback - transition over iniItemNt
       var currItem = iniItem; // iniItem is initial item for all currItem's in the shift chain.
       while (currItem != null) {
     if(sourceItems.Contains(currItem)) {
       // We create transitions lazily, only when we actually need them. Check if we have iniItem's transition
       // in local variable; if not, get it from state's transitions table; if not found, create it.
       if(lookback == null && !state.BuilderData.Transitions.TryGetValue(iniItemNt, out lookback)) {
         lookback = new Transition(state, iniItemNt);
         newTransitions.Add(lookback);
       }
       //Now for currItem, either add trans to Lookbacks, or "include" it into currItem.Transition
       // We need lookbacks ONLY for final items; for non-Final items we need proper Include lists on transitions
       if (currItem.Core.IsFinal)
         currItem.Lookbacks.Add(lookback);
       else // if (currItem.Transition != null)
         // Note: looks like checking for currItem.Transition is redundant - currItem is either:
         //    - Final - always the case for the first run of this method;
         //    - it has a transition after the first run, due to the way we select sourceItems list
         //       in SelectNewItemsThatNeedLookback (by transitions)
         currItem.Transition.Include(lookback);
     }//if
     //move to next item
     currItem = currItem.ShiftedItem;
       }//while
     }//foreach iniItem
       }//foreach state
       return newTransitions;
 }