public ProductionExpressionBuilder(string str)
 {
     expression = new ProductionExpression()
     {
         TypeConventer.ToTerminal(str)
     };
 }
Beispiel #2
0
 private void getFollow()
 {
     Productions[0].Left.Follow.Add(TypeConventer.ToTerminal(Tokens.LexEnd));
     while (true)
     {
         bool loop = false;
         for (var i = 0; i < Productions.Count; i++)
         {
             var left  = Productions[i].Left;
             var right = Productions[i].Right;
             foreach (var proe in right)
             {
                 var flag = true;
                 for (var j = proe.Count - 1; j >= 0; j--)
                 {
                     if (proe[j] is NonTerminal nontJ)
                     {
                         int x = vndic[nontJ];
                         if (flag)
                         {
                             int before = nontJ.Follow.Count;
                             nontJ.Follow.UnionWith(left.Follow);
                             if (!Productions[x].HasEpsilonExpression)
                             {
                                 flag = false;
                             }
                             int after = nontJ.Follow.Count;
                             if (after > before)
                             {
                                 loop = true;
                             }
                         }
                         for (int k = j + 1; k < proe.Count; k++)
                         {
                             if (proe[k] is NonTerminal nontK)
                             {
                                 var from   = nontK.First;
                                 var to     = nontJ.Follow;
                                 int before = to.Count;
                                 foreach (var it1 in from)
                                 {
                                     if (it1 != Terminal.Epsilon)
                                     {
                                         to.Add(it1);
                                     }
                                 }
                                 int after = to.Count;
                                 if (after > before)
                                 {
                                     loop = true;
                                 }
                                 if (!Productions[vndic[nontK]].HasEpsilonExpression)
                                 {
                                     break;
                                 }
                             }
                             else if (proe[k] is Terminal termK)
                             {
                                 int before = nontJ.Follow.Count;
                                 nontJ.Follow.Add(termK);
                                 int after = nontJ.Follow.Count;
                                 if (after > before)
                                 {
                                     loop = true;
                                 }
                                 break;
                             }
                             else
                             {
                                 continue;
                             }
                         }
                     }
                     else
                     {
                         flag = false;
                     }
                 }
             }
         }
         if (!loop)
         {
             break;
         }
     }
 }
 public void Append(string str)
 {
     expression.Add(TypeConventer.ToTerminal(str));
 }