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); }