Example #1
0
        public void CollectIndex(ABnfNodeElement node)
        {
            if (node.GetNodeType() == "Id")
            {
                var value = node.GetElementText();
                HashSet <ABnfNodeElement> set;
                if (!m_index.TryGetValue(value, out set))
                {
                    set = new HashSet <ABnfNodeElement>();
                    m_index.Add(value, set);
                }
                set.Add(node as ABnfNodeElement);
            }

            foreach (var child in node.GetChilds())
            {
                if (child is ABnfNodeElement)
                {
                    CollectIndex(child as ABnfNodeElement);
                }
            }
        }
Example #2
0
        // 分析节点
        bool AnalysisABnfNodeMatch(ABnfRuleInfo rule
                                   , ABnfRuleNodeInfo node, ABnfNodeElement parent, bool not_key
                                   , ref int line, ref int col, ref int offset
                                   , ref int pin_offset, bool ignore_error)
        {
            // 判断是不是叶子节点
            if (node.value != null)
            {
                // 如果是匹配子规则
                if (node.value.type == ABnfRuleTokenType.TT_ID)
                {
                    // 如果没有找到子规则
                    ABnfRuleInfo child = node.value.rule;
                    if (child == null)
                    {
                        child           = m_rule.FindRuleInfo(node.value.value);
                        node.value.rule = child;
                    }
                    if (child == null)
                    {
                        // 如果忽略错误,直接返回false
                        if (ignore_error)
                        {
                            return(false);
                        }
                        // 跳过空格,tab,换行
                        AnalysisSkip(ref line, ref col, ref offset);
                        // 添加错误节点
                        parent.AddChild(new ABnfErrorElement(m_factory, m_file, line, col, offset, "未知规则:" + node.value.value, null));
                        return(false);
                    }

                    // 添加结束符
                    m_stop_stack.Add(child);

                    // 匹配子规则,子规则的pin是不能传出来的
                    bool result = AnalysisABnfRuleMatch(child, parent, node.not_key == ABnfRuleNodeNotKeyType.NNKT_TRUE || not_key
                                                        , ref line, ref col, ref offset
                                                        , ref pin_offset, ignore_error);

                    // 删除结束符
                    m_stop_stack.RemoveAt(m_stop_stack.Count - 1);
                    return(result);
                }

                // 如果是正则表达式
                if (node.value.type == ABnfRuleTokenType.TT_REGEX)
                {
                    return(AnalysisABnfRegexMatch(rule, node, parent, node.not_key == ABnfRuleNodeNotKeyType.NNKT_TRUE || not_key, ref line, ref col, ref offset, ref pin_offset, ignore_error));
                }

                // 如果是关键字
                if (node.value.type == ABnfRuleTokenType.TT_KEY)
                {
                    return(AnalysisABnfKeyMatch(rule, node, parent, node.not_key == ABnfRuleNodeNotKeyType.NNKT_TRUE || not_key, ref line, ref col, ref offset, ignore_error));
                }

                // 剩下的就是普通字符串
                return(AnalysisABnfStringMatch(rule, node, parent, node.not_key == ABnfRuleNodeNotKeyType.NNKT_TRUE || not_key, ref line, ref col, ref offset, ignore_error));
            }

            // 如果是一个组规则

            // 跳过空格,制表符,换行
            AnalysisSkip(ref line, ref col, ref offset);
            // 跳过注释
            AnalysisABnfCommentMatch(rule, parent, not_key, ref line, ref col, ref offset);
            // 跳过空格,制表符,换行
            AnalysisSkip(ref line, ref col, ref offset);

            if (offset >= m_file.m_text.Length)
            {
                return(false);
            }
            char next_char = m_file.m_text[offset];

            if (!node.CheckNextChar(m_rule, next_char, out List <int> index_list))
            {
                return(false);
            }

            // 遍历选择规则
            List <ABnfNodeElement> option_list = null;

            foreach (var option_index in index_list)
            {
                if (!node.PreCheck(m_file, offset))
                {
                    continue;
                }
                var node_list = node.node_list[option_index];

                // 缓存位置
                int temp_line   = line;
                int temp_col    = col;
                int temp_offset = offset;

                // 标记当前规则是否有pin
                int temp_pin_offset = -1;
                // 是否匹配成功
                bool match = true;
                // 开始处理规则
                ABnfNodeElement element = new ABnfNodeElement(m_factory, m_file, line, col, offset, "");
                for (int index = 0; index < node_list.Count; ++index)
                {
                    int sub_pin_offset = -1;
                    if (!AnalysisABnfNode(rule, node_list[index], element, not_key
                                          , ref temp_line, ref temp_col, ref temp_offset
                                          , ref sub_pin_offset, false))
                    {
                        // 如果匹配失败,并且内部有pin,那么当前也要设置为pin
                        if (sub_pin_offset >= 0)
                        {
                            temp_pin_offset = sub_pin_offset;
                        }
                        match = false;
                        break;
                    }

                    // 如果匹配失败,并且内部有pin,那么当前也要设置为pin
                    if (sub_pin_offset >= 0)
                    {
                        temp_pin_offset = sub_pin_offset;
                    }

                    // 如果规则本身有pin,那么也要设置为pin
                    if (node_list[index].pin == ABnfRuleNodePinType.NPT_TRUE)
                    {
                        temp_pin_offset = temp_offset;
                    }
                }

                // 匹配成功
                if (match)
                {
                    // 添加到节点中
                    foreach (var child in element.GetChilds())
                    {
                        if (child.IsLeafOrHasChildOrError())
                        {
                            parent.AddChild(child);
                        }
                    }
                    // 返回结果位置
                    line   = temp_line;
                    col    = temp_col;
                    offset = temp_offset;

                    if (temp_pin_offset >= 0)
                    {
                        pin_offset = temp_pin_offset;
                    }
                    return(true);
                }

                // 如果出现pin,那么对外比较pin
                // 清理之前的节点,添加自己并跳出
                if (temp_pin_offset >= 0)
                {
                    pin_offset = temp_pin_offset;

                    line   = temp_line;
                    col    = temp_col;
                    offset = temp_offset;

                    if (option_list == null)
                    {
                        option_list = new List <ABnfNodeElement>();
                    }
                    option_list.Clear();
                    option_list.Add(element);
                    break;
                }
                // 如果没有出现pin,把错误添加到option_list
                else
                {
                    if (option_list == null)
                    {
                        option_list = new List <ABnfNodeElement>();
                    }
                    option_list.Add(element);
                }
            }

            // 没有pin并且忽略错误的情况下,直接返回false
            if (pin_offset < 0 && ignore_error)
            {
                return(false);
            }

            // 处理option_list
            if (option_list != null)
            {
                foreach (var option in option_list)
                {
                    foreach (var child in option.GetChilds())
                    {
                        if (child.IsLeafOrHasChildOrError())
                        {
                            parent.AddChild(child);
                        }
                    }
                }
            }

            return(false);
        }
Example #3
0
        // 规则节点
        bool AnalysisABnfRuleMatch(ABnfRuleInfo rule, ABnfNodeElement parent, bool not_key
                                   , ref int line, ref int col, ref int offset
                                   , ref int pin_offset, bool ignore_error)
        {
            // 跳过空格,制表符,换行
            AnalysisSkip(ref line, ref col, ref offset);
            // 跳过注释
            AnalysisABnfCommentMatch(rule, parent, not_key, ref line, ref col, ref offset);
            // 跳过空格,制表符,换行
            AnalysisSkip(ref line, ref col, ref offset);

            if (offset >= m_file.m_text.Length)
            {
                return(false);
            }
            char next_char = m_file.m_text[offset];

            if (!rule.CheckNextChar(next_char, out List <int> index_list))
            {
                return(false);
            }

            // 遍历选择规则
            List <ABnfNodeElement> option_list = null;

            foreach (var option_index in index_list)
            {
                if (!rule.node.PreCheck(m_file, offset))
                {
                    continue;
                }
                var node_list = rule.node.node_list[option_index];

                // 缓存位置
                int temp_line   = line;
                int temp_col    = col;
                int temp_offset = offset;

                // 标记当前规则是否有pin
                int temp_pin_offset = -1;
                // 是否匹配成功
                bool match = true;
                // 开始处理规则
                ABnfNodeElement element = CreateNodeElement(line, col, offset, rule.id.value);
                for (int index = 0; index < node_list.Count; ++index)
                {
                    int sub_pin_offset = -1;
                    if (!AnalysisABnfNode(rule, node_list[index], element, not_key
                                          , ref temp_line, ref temp_col, ref temp_offset
                                          , ref sub_pin_offset, false))
                    {
                        // 如果匹配失败,并且内部有pin,那么当前也要设置为pin
                        if (sub_pin_offset >= 0)
                        {
                            temp_pin_offset = sub_pin_offset;
                        }
                        match = false;
                        break;
                    }

                    // 如果匹配失败,并且内部有pin,那么当前也要设置为pin
                    if (sub_pin_offset >= 0)
                    {
                        temp_pin_offset = sub_pin_offset;
                    }

                    // 如果规则本身有pin,那么也要设置为pin
                    if (node_list[index].pin == ABnfRuleNodePinType.NPT_TRUE)
                    {
                        temp_pin_offset = temp_offset;
                    }
                }

                // 匹配成功
                if (match)
                {
                    // 添加到节点中
                    if (element.GetChilds().Count != 0)
                    {
                        parent.AddChild(element);
                    }
                    // 返回结果位置
                    line   = temp_line;
                    col    = temp_col;
                    offset = temp_offset;

                    if (temp_pin_offset >= 0)
                    {
                        pin_offset = temp_pin_offset;
                    }
                    return(true);
                }

                // 如果出现pin,那么对外比较pin
                // 清理之前的节点,添加自己并跳出
                if (temp_pin_offset >= 0)
                {
                    pin_offset = temp_pin_offset;

                    line   = temp_line;
                    col    = temp_col;
                    offset = temp_offset;

                    if (option_list == null)
                    {
                        option_list = new List <ABnfNodeElement>();
                    }
                    option_list.Clear();
                    option_list.Add(element);
                    break;
                }
                // 如果没有出现pin,把错误添加到option_list
                else
                {
                    if (option_list == null)
                    {
                        option_list = new List <ABnfNodeElement>();
                    }
                    option_list.Add(element);
                }
            }

            // 没有pin并且忽略错误的情况下,直接返回false
            if (pin_offset < 0 && ignore_error)
            {
                return(false);
            }

            // 处理option_list
            if (option_list != null)
            {
                foreach (var option in option_list)
                {
                    if (option.GetChilds().Count != 0)
                    {
                        parent.AddChild(option);
                    }
                }
            }

            // 如果有pin,并且有结束符
            if (pin_offset >= 0)
            {
                // 从pin_offset开始查找结束符
                int find  = m_file.m_text.Length;
                int index = -1;
                for (int i = m_stop_stack.Count - 1; i >= 0; --i)
                {
                    string stop_token = m_stop_stack[i].GetStopToken();
                    if (stop_token == null)
                    {
                        continue;
                    }

                    int value = m_file.m_text.IndexOf(stop_token, pin_offset, find - pin_offset);
                    if (value >= 0 && find > value)
                    {
                        find  = value;
                        index = i;
                    }
                }
                if (index >= 0)
                {
                    if (m_stop_stack[index] == rule)
                    {
                        AnalysisOffset(find + m_stop_stack[index].GetStopToken().Length - offset, ref line, ref col, ref offset);
                        parent.AddChild(new ABnfErrorElement(m_factory, m_file, line, col, offset, "语法错误", null));
                        return(true);
                    }
                    else if (index == m_stop_stack.Count - 2)
                    {
                        AnalysisOffset(find - offset, ref line, ref col, ref offset);
                        parent.AddChild(new ABnfErrorElement(m_factory, m_file, line, col, offset, "语法错误", null));
                        return(true);
                    }
                }
            }

            return(false);
        }