internal static int[] BindMethodBase(Reduction ruleDeclaration, MethodBase methodBase, bool allowTruncation, bool bijectiveMapping) {
			ParameterInfo[] parameters = methodBase.GetParameters();
			int[] mapping = new int[parameters.Length];
			for (int i = 0; i < mapping.Length; i++) {
				mapping[i] = -1;
				if (parameters[i].ParameterType.IsValueType) {
					throw new InvalidOperationException("Only reference types are allowed as "+methodBase.MemberType+" parameters when binding to rules");
				}
			}
			int index = 0;
			foreach (int ruleHandleIndex in GetRuleHandleIndexes(ruleDeclaration)) {
				if (ruleHandleIndex >= 0) {
					if (ruleHandleIndex >= mapping.Length) {
						if (!allowTruncation) {
							throw new InvalidOperationException("The "+methodBase.MemberType+" parameter mapping is not allowed to be truncated");
						}
					} else {
						if (mapping[ruleHandleIndex] >= 0) {
							throw new InvalidOperationException("Only one handle can be assigned per "+methodBase.MemberType+" parameter");
						}
						mapping[ruleHandleIndex] = index;
					}
				}
				index++;
			}
			if (bijectiveMapping) {
				bool failed = false;
				foreach (int i in mapping) {
					failed |= i < 0;
				}
				if (failed) {
					throw new InvalidOperationException("Strict parameter matching is set - each parameter must be matched to a symbol.");
				}
			}
			return mapping;
		}
 internal static bool TryParse(string ruleString, out Reduction ruleToken)
 {
     using (StringReader reader = new StringReader(ruleString)) {
         Tokenizer tokenizer = new Tokenizer(reader, ruleGrammar);
         LalrProcessor processor = new LalrProcessor(tokenizer);
         ParseMessage message;
         do {
             message = processor.Parse();
             if (message == ParseMessage.Accept) {
                 ruleToken = (Reduction)processor.CurrentToken;
                 return true;
             }
         } while (CompiledGrammar.CanContinueParsing(message));
     }
     ruleToken = null;
     return false;
 }
 internal static bool TryBindGrammar(Reduction ruleDeclaration, CompiledGrammar grammar, out Rule rule)
 {
     Symbol ruleSymbol;
     if (grammar.TryGetSymbol(GetRuleSymbolName(ruleDeclaration), out ruleSymbol)) {
         ReadOnlyCollection<Rule> rules;
         if (grammar.TryGetRulesForSymbol(ruleSymbol, out rules)) {
             List<Symbol> symbols = new List<Symbol>();
             foreach (string handleName in GetRuleHandleNames(ruleDeclaration)) {
                 Symbol symbol;
                 if (!grammar.TryGetSymbol(handleName, out symbol)) {
                     symbols = null;
                     break;
                 }
                 symbols.Add(symbol);
             }
             if (symbols != null) {
                 foreach (Rule currentRule in rules) {
                     if (currentRule.Matches(symbols)) {
                         rule = currentRule;
                         return true;
                     }
                 }
             }
         }
     }
     rule = null;
     return false;
 }
 internal static string GetRuleSymbolName(Reduction ruleDeclaration)
 {
     if (ruleDeclaration == null) {
         throw new ArgumentNullException("ruleDeclaration");
     }
     return ruleDeclaration.Children[0].ToString();
 }
 internal static IEnumerable<string> GetRuleHandleNames(Reduction ruleDeclaration)
 {
     if (ruleDeclaration == null) {
         throw new ArgumentNullException("ruleDeclaration");
     }
     Reduction handle = (Reduction)ruleDeclaration.Children[2];
     while (handle.Children.Count == 2) {
         Reduction handleSymbol = (Reduction)handle.Children[0];
         yield return handleSymbol.Children[handleSymbol.Children.Count-1].ToString();
         handle = (Reduction)handle.Children[1];
     }
 }
 internal static IEnumerable<int> GetRuleHandleIndexes(Reduction ruleDeclaration)
 {
     if (ruleDeclaration == null) {
         throw new ArgumentNullException("ruleDeclaration");
     }
     Reduction handle = (Reduction)ruleDeclaration.Children[2];
     int index = 0;
     List<int> emittedIndexes = new List<int>();
     while (handle.Children.Count == 2) {
         Reduction handleSymbol = (Reduction)handle.Children[0];
         TextToken offset = handleSymbol.Children[0] as TextToken;
         if (offset != null) {
             if (offset.Text == "~") {
                 yield return -1;
             } else {
                 int result = int.Parse(offset.Text.TrimEnd(' ', ':'), NumberFormatInfo.InvariantInfo);
                 emittedIndexes.Add(result);
                 yield return result;
             }
         } else {
             while (emittedIndexes.Contains(index)) {
                 index++;
             }
             emittedIndexes.Add(index);
             yield return index++;
         }
         handle = (Reduction)handle.Children[1];
     }
 }