public bool CheckNextChar(ABnfRule rule, char next, out List <int> index_list) { index_list = null; if (!calc_next_char) { CalcNextChar(rule); } if (next_char_map == null) { return(true); } if (next_char_map.TryGetValue(next, out List <int> list)) { index_list = list; return(true); } return(false); }
public ABnfRuleInfo(ABnfRule r) { rule = r; }
public Dictionary <char, List <int> > CalcNextChar(ABnfRule rule) { // 判断是否已经计算 if (calc_next_char) { return(next_char_map); } calc_next_char = true; CalcPreCheck(); // 如果不是组,直接返回 if (node_list == null) { return(next_char_map); } // 创建对象 next_char_map = new Dictionary <char, List <int> >(); // 遍历可选序列 for (int index = 0; index < node_list.Count; ++index) { // 遍历规则序列 for (int i = 0; i < node_list[index].Count; ++i) { var node_value = node_list[index][i]; // 如果是子规则 if (node_value.value != null) { // 子规则 if (node_value.value.type == ABnfRuleTokenType.TT_ID) { // 查找子规则 var sub_rule = rule.FindRuleInfo(node_value.value.value); if (sub_rule == null) { next_char_map = null; return(next_char_map); } // 子规则计算 var sub_next_char_map = sub_rule.CalcNextChar(); if (sub_next_char_map == null) { next_char_map = null; return(next_char_map); } // 遍历合并 foreach (var pair in sub_next_char_map) { if (!next_char_map.TryGetValue(pair.Key, out List <int> list)) { list = new List <int>(); next_char_map.Add(pair.Key, list); } if (!list.Contains(index)) { list.Add(index); } } } // 如果遇到正则表达式,那么直接设置为无预测 else if (node_value.value.type == ABnfRuleTokenType.TT_REGEX) { next_char_map = null; return(next_char_map); } else if (node_value.value.type == ABnfRuleTokenType.TT_STRING || node_value.value.type == ABnfRuleTokenType.TT_KEY) { if (node_value.value.value.Length > 0) { if (!next_char_map.TryGetValue(node_value.value.value[0], out List <int> list)) { list = new List <int>(); next_char_map.Add(node_value.value.value[0], list); } if (!list.Contains(index)) { list.Add(index); } } } } // 如果是组规则 else { var sub_next_char_map = node_value.CalcNextChar(rule); if (sub_next_char_map == null) { next_char_map = null; return(next_char_map); } foreach (var pair in sub_next_char_map) { if (!next_char_map.TryGetValue(pair.Key, out List <int> list)) { list = new List <int>(); next_char_map.Add(pair.Key, list); } if (!list.Contains(index)) { list.Add(index); } } } if (node_value.repeat != ABnfRuleNodeRepeatType.NRT_NOT_OR_MORE && node_value.repeat != ABnfRuleNodeRepeatType.NRT_ONE_OR_NOT) { break; } } } return(next_char_map); }