}                     //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
        }                     //method

        #endregion

        #region Calculating Tail Firsts
        private void CalculateTailFirsts()
        {
            foreach (Production prod in Data.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     term   = prod.RValues[item.Position + 1]; //Element after-after-dot
                    NonTerminal ntElem = term as NonTerminal;
                    if (ntElem == null || !ntElem.Nullable)               //term is 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 (ntElem == null)
                        {
                            item.TailFirsts.Add(term.Key);//term is terminal so add its key
                            accumulatedFirsts.Add(term.Key);
                        }
                        else
                        {
                            item.TailFirsts.AddRange(ntElem.Firsts); //nonterminal
                            accumulatedFirsts.AddRange(ntElem.Firsts);
                        }
                        continue;
                    }
                    //if we are here, then ntElem is a nullable NonTerminal. We add
                    accumulatedFirsts.AddRange(ntElem.Firsts);
                    item.TailFirsts.AddRange(accumulatedFirsts);
                    item.TailIsNullable = allNullable;
                } //for i
            }     //foreach prod
        }         //method
Beispiel #3
0
 public Adapters(DataGroups dataGroups, params string[] validAdapterNames)
 {
     this.dataGroups = dataGroups;
     adapters        = new StringHash <Adapter <T> >(true);
     validAdapters   = new StringSet(true);
     if (validAdapterNames.Length == 0)
     {
         isValidAdapterName = _ => true;
     }
     else
     {
         isValidAdapterName = adapterName => adapterName.IsNotEmpty() && validAdapters.Contains(adapterName);
         validAdapters.AddRange(validAdapterNames);
     }
 }
Beispiel #4
0
        //TODO: This needs more work. Currently it reports all individual symbols most of the time, in a message like
        //  "Syntax error, expected: + - < > = ..."; the better method is to group operator symbols under one alias "operator".
        // The reason is that code picks expected key list at current(!) state only,
        // slightly tweaking it for non-terminals, without exploring Reduce roots
        // It is quite difficult to discover grouping non-terminals like "operator" in current structure.
        // One possible solution would be to introduce "ExtendedLookaheads" in ParserState which would include
        // all NonTerminals that might follow the current position. This list would be calculated at start up,
        // in addition to normal lookaheads.
        #endregion
        private StringList GetCurrentExpectedSymbols()
        {
            BnfTermList inputElements = new BnfTermList();
            StringSet   inputKeys     = new StringSet();

            inputKeys.AddRange(_currentState.Actions.Keys);
            //First check all NonTerminals
            foreach (NonTerminal nt in Data.NonTerminals)
            {
                if (!inputKeys.Contains(nt.Key))
                {
                    continue;
                }
                //nt is one of our available inputs; check if it has an alias. If not, don't add it to element list;
                // and we have already all its "Firsts" keys in the list.
                // If yes, add nt to element list and remove
                // all its "fists" symbols from the list. These removed symbols will be represented by single nt alias.
                if (string.IsNullOrEmpty(nt.DisplayName))
                {
                    inputKeys.Remove(nt.Key);
                }
                else
                {
                    inputElements.Add(nt);
                    foreach (string first in nt.Firsts)
                    {
                        inputKeys.Remove(first);
                    }
                }
            }
            //Now terminals
            foreach (Terminal term in Data.Terminals)
            {
                if (inputKeys.Contains(term.Key))
                {
                    inputElements.Add(term);
                }
            }
            StringList result = new StringList();

            foreach (BnfTerm term in inputElements)
            {
                result.Add(string.IsNullOrEmpty(term.DisplayName)? term.Name : term.DisplayName);
            }
            result.Sort();
            return(result);
        }
Beispiel #5
0
 private StringList GetCurrentExpectedSymbols()
 {
     BnfTermList inputElements = new BnfTermList();
       StringSet inputKeys = new StringSet();
       inputKeys.AddRange(_currentState.Actions.Keys);
       //First check all NonTerminals
       foreach (NonTerminal nt in Data.NonTerminals) {
     if (!inputKeys.Contains(nt.Key)) continue;
     //nt is one of our available inputs; check if it has an alias. If not, don't add it to element list;
     // and we have already all its "Firsts" keys in the list.
     // If yes, add nt to element list and remove
     // all its "fists" symbols from the list. These removed symbols will be represented by single nt alias.
     if (string.IsNullOrEmpty(nt.DisplayName))
       inputKeys.Remove(nt.Key);
     else {
       inputElements.Add(nt);
       foreach(string first in nt.Firsts)
     inputKeys.Remove(first);
     }
       }
       //Now terminals
       foreach (Terminal term in Data.Terminals) {
     if (inputKeys.Contains(term.Key))
       inputElements.Add(term);
       }
       StringList result = new StringList();
       foreach(BnfTerm term in inputElements)
     result.Add(string.IsNullOrEmpty(term.DisplayName)? term.Name : term.DisplayName);
       result.Sort();
       return result;
 }
    private void CalculateTailFirsts()
    {
      foreach (Production prod in _data.Productions)
      {
        StringSet accumulatedFirsts = new StringSet();
        bool allNullable = true;

        for (int i = prod.LR0Items.Count - 1; i >= 0; i--)
        {
          LR0Item item = prod.LR0Items[i];
          if (i >= prod.LR0Items.Count - 2)
          {
            item.TailIsNullable = true;
            item.TailFirsts.Clear();
            continue;
          }
          GrammarTerm term = prod.RValues[item.Position + 1]; 
          NonTerminal ntElem = term as NonTerminal;
          if (ntElem == null || !ntElem.Nullable)
          { 
            accumulatedFirsts.Clear();
            allNullable = false;
            item.TailIsNullable = false;
            if (ntElem == null)
            {
              item.TailFirsts.Add(term.Key);
              accumulatedFirsts.Add(term.Key);
            }
            else
            {
              item.TailFirsts.AddRange(ntElem.Firsts); 
              accumulatedFirsts.AddRange(ntElem.Firsts);
            }
            continue;
          }
          accumulatedFirsts.AddRange(ntElem.Firsts);
          item.TailFirsts.AddRange(accumulatedFirsts);
          item.TailIsNullable = allNullable;
        }
      }
    }
Beispiel #7
0
        public readonly UnicodeCategoryList CharsToRemoveCategories = new UnicodeCategoryList(); //categories of chars to remove from final id, usually formatting category
        #endregion

        public void AddKeywords(params string[] keywords)
        {
            Keywords.AddRange(keywords);
        }