protected virtual void RegisterTerminalFactory(Symbol symbol, SemanticTerminalFactory <T> factory) { if (symbol == null) { throw new ArgumentNullException("symbol"); } if (symbol.Owner != grammar) { throw new ArgumentException("The symbol was defined on another grammar", "symbol"); } if (symbol.Kind == SymbolKind.Nonterminal) { throw new ArgumentException("Terminal symbol factories can only build terminals and special symbols", "symbol"); } if (factory == null) { throw new ArgumentNullException("factory"); } AssertNotInitialized(); terminalFactories.Add(symbol, factory); }
protected override void RegisterTerminalFactory(Symbol symbol, SemanticTerminalFactory <T> factory) { base.RegisterTerminalFactory(symbol, factory); MemorizeType(factory, symbol); }
public bool TryGetTerminalFactory(Symbol symbol, out SemanticTerminalFactory <T> factory) { Initialize(); return(terminalFactories.TryGetValue(symbol, out factory)); }
protected override void InitializeInternal(ICollection <string> errors, bool trace, bool strongParameterCheck) { foreach (Type type in typeof(T).Assembly.GetTypes()) { if (typeof(T).IsAssignableFrom(type) && type.IsClass && (!type.IsAbstract)) { SemanticTerminalFactory <T> terminalFactory = null; foreach (TerminalAttribute terminalAttribute in type.GetCustomAttributes(typeof(TerminalAttribute), true)) { Symbol symbol = terminalAttribute.Bind(Grammar); if (symbol == null) { errors.Add(string.Format("Terminal {0} not found in grammar", terminalAttribute.SymbolName)); } else { try { Type factoryType = (terminalAttribute.IsGeneric) ? type.MakeGenericType(terminalAttribute.GenericTypes) : type; if (terminalFactory == null) { terminalFactory = CreateTerminalFactory(factoryType); } RegisterTerminalFactory(symbol, terminalFactory); if (factoryType != type) { terminalFactory = null; // don't keep generic factories } } catch (TargetInvocationException ex) { errors.Add(string.Format("Terminal {0} factory problem: {1}", symbol, ex.InnerException.Message)); } catch (Exception ex) { errors.Add(string.Format("Terminal {0} factory problem: {1}", symbol, ex.Message)); } } } foreach (ConstructorInfo constructor in type.GetConstructors()) { foreach (RuleAttribute ruleAttribute in constructor.GetCustomAttributes(typeof(RuleAttribute), true)) { ProcessAttribute(errors, strongParameterCheck, ruleAttribute, type, constructor, GetConstructorFactoryType); } } } //examine the static methods foreach (MethodInfo methodInfo in type.GetMethods()) { if (typeof(T).IsAssignableFrom(methodInfo.ReturnType)) { foreach (RuleAttribute ruleAttribute in methodInfo.GetCustomAttributes(typeof(RuleAttribute), true)) { if (methodInfo.IsStatic) { ProcessAttribute(errors, strongParameterCheck, ruleAttribute, type, methodInfo, GetMethodFactoryType); } else { errors.Add(string.Format("Rule {0} is assigned to a non-static method, which is not allowed.", ruleAttribute.Rule)); } } } } } // finally we look for all trim rules in the assembly foreach (RuleTrimAttribute ruleTrimAttribute in typeof(T).Assembly.GetCustomAttributes(typeof(RuleTrimAttribute), false)) { if ((ruleTrimAttribute.SemanticTokenType == null) || typeof(T).Equals(ruleTrimAttribute.SemanticTokenType)) { Rule rule = ruleTrimAttribute.Bind(Grammar); if (rule == null) { errors.Add(string.Format("Rule {0} not found in grammar", ruleTrimAttribute.Rule)); } else { try { RegisterNonterminalFactory(rule, new SemanticTrimFactory <T>(this, rule, ruleTrimAttribute.TrimSymbolIndex)); } catch (InvalidOperationException ex) { errors.Add(string.Format("Trim tule {0} factory problem: {1}", rule, ex.Message)); } } } } }