Beispiel #1
0
 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;
 }
Beispiel #3
0
        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);
        }