예제 #1
0
        public static BuildResult <ParserConfiguration <IN, OUT> > BuildExpressionRules <IN, OUT>(
            ParserConfiguration <IN, OUT> configuration, Type parserClass,
            BuildResult <ParserConfiguration <IN, OUT> > result) where IN : struct
        {
            var methods = parserClass.GetMethods().ToList();

            methods = methods.Where(m =>
            {
                var attributes = m.GetCustomAttributes().ToList();
                var attr       = attributes.Find(a => a.GetType() == typeof(OperationAttribute));
                return(attr != null);
            }).ToList();

            var operationsByPrecedence = new Dictionary <int, List <OperationMetaData <IN> > >();

            methods.ForEach(m =>
            {
                var attributes =
                    (OperationAttribute[])m.GetCustomAttributes(typeof(OperationAttribute), true);

                foreach (var attr in attributes)
                {
                    IN oper = default;
                    if (attr.IsIntToken)
                    {
                        oper = EnumConverter.ConvertIntToEnum <IN>(attr.IntToken);
                    }
                    else if (attr.IsStringToken)
                    {
                        oper = EnumConverter.ConvertStringToEnum <IN>(attr.StringToken);
                    }
                    var operation  = new OperationMetaData <IN>(attr.Precedence, attr.Assoc, m, attr.Affix, oper);
                    var operations = new List <OperationMetaData <IN> >();
                    if (operationsByPrecedence.ContainsKey(operation.Precedence))
                    {
                        operations = operationsByPrecedence[operation.Precedence];
                    }
                    operations.Add(operation);
                    operationsByPrecedence[operation.Precedence] = operations;
                }
            });

            if (operationsByPrecedence.Count > 0)
            {
                var operandNonTerminal = GetOperandNonTerminal(parserClass, configuration, result);


                if (operandNonTerminal != null && operationsByPrecedence.Count > 0)
                {
                    GenerateExpressionParser(configuration, operandNonTerminal, operationsByPrecedence,
                                             parserClass.Name);
                }
            }

            result.Result = configuration;
            return(result);
        }
        public static BuildResult <ParserConfiguration <IN, OUT> > BuildExpressionRules <IN, OUT>(
            ParserConfiguration <IN, OUT> configuration, Type parserClass,
            BuildResult <ParserConfiguration <IN, OUT> > result) where IN : struct
        {
            var methods = parserClass.GetMethods().ToList();

            methods = methods.Where(m =>
            {
                var attributes = m.GetCustomAttributes().ToList();
                var attr       = attributes.Find(a => a.GetType() == typeof(OperationAttribute));
                return(attr != null);
            }).ToList();

            var operationsByPrecedence = new Dictionary <int, List <OperationMetaData <IN> > >();

            methods.ForEach(m =>
            {
                var attributes =
                    (OperationAttribute[])m.GetCustomAttributes(typeof(OperationAttribute), true);

                foreach (var attr in attributes)
                {
                    IN oper = default;
                    if (attr.IsIntToken)
                    {
                        oper = EnumConverter.ConvertIntToEnum <IN>(attr.IntToken);
                    }
                    else if (attr.IsStringToken)
                    {
                        oper = EnumConverter.ConvertStringToEnum <IN>(attr.StringToken);
                    }
                    var operation  = new OperationMetaData <IN>(attr.Precedence, attr.Assoc, m, attr.Affix, oper);
                    var operations = new List <OperationMetaData <IN> >();
                    if (operationsByPrecedence.ContainsKey(operation.Precedence))
                    {
                        operations = operationsByPrecedence[operation.Precedence];
                    }
                    operations.Add(operation);
                    operationsByPrecedence[operation.Precedence] = operations;
                }
            });

            if (operationsByPrecedence.Count > 0)
            {
                methods = parserClass.GetMethods().ToList();
                var operandMethod = methods.Find(m =>
                {
                    var attributes = m.GetCustomAttributes().ToList();
                    var attr       = attributes.Find(a => a.GetType() == typeof(OperandAttribute));
                    return(attr != null);
                });

                string operandNonTerminal = null;

                if (operandMethod == null)
                {
                    result.AddError(new ParserInitializationError(ErrorLevel.FATAL, "missing [operand] attribute"));
                    throw new Exception("missing [operand] attribute");
                }

                var production =
                    operandMethod.GetCustomAttributes().ToList()
                    .Find(attr => attr.GetType() == typeof(ProductionAttribute)) as ProductionAttribute;
                if (production != null)
                {
                    var ruleItems = production.RuleString.Split(':');
                    if (ruleItems.Length > 0)
                    {
                        operandNonTerminal = ruleItems[0].Trim();
                    }
                }


                if (operandNonTerminal != null && operationsByPrecedence.Count > 0)
                {
                    GenerateExpressionParser(configuration, operandNonTerminal, operationsByPrecedence,
                                             parserClass.Name);
                }
            }

            result.Result = configuration;
            return(result);
        }