Beispiel #1
0
        /// <summary>
        /// 构造产生式。
        /// </summary>
        /// <param name="symbolMapper">符号的映射表。</param>
        public void BuildProductions(Dictionary <T, Symbol <T> > symbolMapper)
        {
            int len = bodies.Length;

            productions = new Production <T> [len];
            for (int i = 0; i < len; i++)
            {
                ProductionBody <T> body = bodies[i];
                int          cnt        = body.Body.Count;
                Symbol <T>[] symbolBody = new Symbol <T> [cnt];
                for (int j = 0; j < cnt; j++)
                {
                    T          id = body.Body[j];
                    Symbol <T> sym;
                    if (symbolMapper.TryGetValue(id, out sym))
                    {
                        symbolBody[j] = sym;
                    }
                    else if (EqualityComparer <T> .Default.Equals(id, Token <T> .Error))
                    {
                        symbolBody[j] = Error;
                    }
                    else
                    {
                        throw CompilerCommonExceptions.InvalidSymbolId("body", id.ToString());
                    }
                }
                Terminal <T> prec = null;
                if (body.PrecedenceSet)
                {
                    Symbol <T> sym;
                    if (!symbolMapper.TryGetValue(body.Precedence, out sym))
                    {
                        throw CompilerCommonExceptions.InvalidSymbolId("Precedence", body.Precedence.ToString());
                    }
                    prec = sym as Terminal <T>;
                    if (prec == null)
                    {
                        throw CompilerCommonExceptions.InvalidSymbolId("Precedence", body.Precedence.ToString());
                    }
                }
                else
                {
                    // 使用最右的终结符代表当前产生式的结合性。
                    for (int j = symbolBody.Length - 1; j >= 0; j--)
                    {
                        Terminal <T> sym = symbolBody[j] as Terminal <T>;
                        if (sym != null)
                        {
                            prec = sym;
                            break;
                        }
                    }
                }
                productions[i] = new Production <T>(body.Index, this, symbolBody, body.ProductionAction, prec);
            }
        }
Beispiel #2
0
 /// <summary>
 /// 检查指定符号的标识符。
 /// </summary>
 /// <param name="id">要检查的标识符。</param>
 public void CheckSymbolId(T id)
 {
     if (EqualityComparer <T> .Default.Equals(id, Token <T> .EndOfFile) ||
         EqualityComparer <T> .Default.Equals(id, Token <T> .Error))
     {
         throw CompilerCommonExceptions.InvalidSymbolId("id", id.ToString());
     }
     else if (Constants.ToInt32(id) < 0)
     {
         throw CompilerCommonExceptions.InvalidSymbolId("id", id.ToString());
     }
     if (symbolIds.ContainsKey(id))
     {
         throw CompilerCommonExceptions.DuplicatedSymbolId("id", id.ToString());
     }
 }
Beispiel #3
0
 /// <summary>
 /// 返回产生式体。
 /// </summary>
 /// <param name="bodies">产生式体包含的终结符或非终结符。</param>
 /// <returns>产生式体。</returns>
 public ProductionBody <T> Body(params T[] bodies)
 {
     for (int i = 0; i < bodies.Length; i++)
     {
         if (EqualityComparer <T> .Default.Equals(bodies[i], Token <T> .EndOfFile))
         {
             throw CompilerCommonExceptions.InvalidSymbolId("bodies", bodies[i].ToString());
         }
         else if (!EqualityComparer <T> .Default.Equals(bodies[i], Token <T> .Error) &&
                  Constants.ToInt32(bodies[i]) < 0)
         {
             throw CompilerCommonExceptions.InvalidSymbolId("bodies", bodies[i].ToString());
         }
     }
     return(new ProductionBody <T>(productionCount++, bodies ?? new T[0]));
 }