Exemple #1
0
        // 字符串匹配
        bool AnalysisABnfStringMatch(ABnfRuleInfo rule
                                     , ABnfRuleNodeInfo node, ABnfNodeElement parent, bool not_key
                                     , ref int line, ref int col, ref int offset
                                     , bool ignore_error)
        {
            // 跳过空格,制表符,换行
            AnalysisSkip(ref line, ref col, ref offset);
            bool succeed = true;

            for (int i = 0; i < node.value.value.Length; ++i)
            {
                // 匹配失败
                if (offset + i >= m_file.m_text.Length ||
                    node.value.value[i] != m_file.m_text[offset + i])
                {
                    succeed = false;
                    break;
                }
            }

            // 检查
            if (succeed)
            {
                int next = offset + node.value.value.Length;
                if (next < m_file.m_text.Length)
                {
                    if (m_symbol_check.TryGetValue(node.value.value, out HashSet <char> set))
                    {
                        if (set.Contains(m_file.m_text[next]))
                        {
                            succeed = false;
                        }
                    }
                }
            }

            if (!succeed)
            {
                // 如果是注释就跳过
                if (rule == m_line_comment || rule == m_block_comment)
                {
                    return(false);
                }
                // 如果忽略错误就跳过
                if (ignore_error)
                {
                    return(false);
                }
                // 添加错误节点
                if (offset < m_file.m_text.Length)
                {
                    parent.AddChild(new ABnfErrorElement(m_factory, m_file, line, col, offset, rule.id.value + "期望匹配" + node.value.value + " 却得到" + m_file.m_text[offset], new ABnfStringElement(m_factory, m_file, line, col, offset, node.value.value)));
                }
                else
                {
                    parent.AddChild(new ABnfErrorElement(m_factory, m_file, line, col, offset, rule.id.value + "期望匹配" + node.value.value + " 却得到文件结尾", new ABnfStringElement(m_factory, m_file, line, col, offset, node.value.value)));
                }
                return(false);
            }

            // 添加正确的节点
            parent.AddChild(CreateStringElement(line, col, offset, node.value.value));
            AnalysisOffset(node.value.value.Length, ref line, ref col, ref offset);
            return(true);
        }
Exemple #2
0
        // 关键字匹配
        bool AnalysisABnfKeyMatch(ABnfRuleInfo rule
                                  , ABnfRuleNodeInfo node, ABnfNodeElement parent, bool not_key
                                  , ref int line, ref int col, ref int offset
                                  , bool ignore_error)
        {
            // 跳过空格,制表符,换行
            AnalysisSkip(ref line, ref col, ref offset);

            bool succeed = true;

            for (int i = 0; i < node.value.value.Length; ++i)
            {
                // 匹配失败
                if (offset + i >= m_file.m_text.Length ||
                    node.value.value[i] != m_file.m_text[offset + i])
                {
                    succeed = false;
                    break;
                }
            }

            if (succeed)
            {
                int next_offset = offset + node.value.value.Length;
                if (next_offset < m_file.m_text.Length)
                {
                    char next_char = m_file.m_text[next_offset];
                    if (next_char >= '0' && next_char <= '9' ||
                        next_char >= 'a' && next_char <= 'z' ||
                        next_char >= 'A' && next_char <= 'Z' ||
                        next_char == '_')
                    {
                        succeed = false;
                    }
                }
            }

            if (!succeed)
            {
                // 如果是注释就跳过
                if (rule == m_line_comment || rule == m_block_comment)
                {
                    return(false);
                }
                // 如果忽略错误就跳过
                if (ignore_error)
                {
                    return(false);
                }
                // 添加错误节点
                if (offset < m_file.m_text.Length)
                {
                    parent.AddChild(new ABnfErrorElement(m_factory, m_file, line, col, offset, rule.id.value + "期望匹配" + node.value.value + " 却得到" + m_file.m_text[offset], new ABnfKeyElement(m_factory, m_file, line, col, offset, node.value.value)));
                }
                else
                {
                    parent.AddChild(new ABnfErrorElement(m_factory, m_file, line, col, offset, rule.id.value + "期望匹配" + node.value.value + " 却得到文件结尾", new ABnfKeyElement(m_factory, m_file, line, col, offset, node.value.value)));
                }
                return(false);
            }

            // 添加正确的节点
            parent.AddChild(CreateKeyElement(line, col, offset, node.value.value));
            AnalysisOffset(node.value.value.Length, ref line, ref col, ref offset);
            return(true);
        }
Exemple #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);
        }
Exemple #4
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);
        }
Exemple #5
0
        // 正则表达式匹配
        bool AnalysisABnfRegexMatch(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)
        {
            // 跳过空格,制表符,换行
            AnalysisSkip(ref line, ref col, ref offset);

            // 获取缓存
            int length = 0;
            Dictionary <ABnfRuleNodeInfo, int> map;
            bool cache = m_regex_skip.TryGetValue(offset, out map) && map.TryGetValue(node, out length);

            if (!cache)
            {
                // 正则表达式匹配
                if (node.value.regex == null)
                {
                    node.value.regex = new Regex(node.value.value, RegexOptions.Compiled);
                }
                // 开始匹配
                var match = node.value.regex.Match(m_file.m_text, offset, m_file.m_text.Length - offset);
                if (match != null && match.Success && match.Index == offset)
                {
                    length = match.Value.Length;
                }
                // 如果没有匹配到,并且规则的预测值有pin
                if (length == 0 && rule.prediction != null && rule.prediction_pin == ABnfRuleNodePinType.NPT_TRUE)
                {
                    // 正则表达式匹配
                    if (rule.prediction.regex == null)
                    {
                        rule.prediction.regex = new Regex(rule.prediction.value, RegexOptions.Compiled);
                    }
                    // 预测匹配
                    var pre_match = rule.prediction.regex.Match(m_file.m_text, offset, m_file.m_text.Length - offset);
                    if (pre_match != null && pre_match.Success && pre_match.Index == offset)
                    {
                        length = -pre_match.Value.Length;
                    }
                }
                // 添加缓存
                if (map == null)
                {
                    map = new Dictionary <ABnfRuleNodeInfo, int>();
                    m_regex_skip.Add(offset, map);
                }
                map.Add(node, length);
            }

            // 如果有找到,那么就添加正确节点
            if (length > 0)
            {
                string value = m_file.m_text.Substring(offset, length);
                // 正则表达式匹配的结果不能是关键字
                if (not_key || !m_rule.GetKeySet().Contains(value))
                {
                    parent.AddChild(CreateRegexElement(line, col, offset, value, node.value.regex));
                    AnalysisOffset(length, ref line, ref col, ref offset);
                    return(true);
                }
            }

            // 如果是注释那么不添加错误节点
            if (rule == m_line_comment || rule == m_block_comment)
            {
                return(false);
            }
            // 如果忽略错误,也不添加错误节点
            if (ignore_error)
            {
                return(false);
            }

            // 添加错误节点
            if (offset < m_file.m_text.Length)
            {
                if (length > 0)
                {
                    parent.AddChild(new ABnfErrorElement(m_factory, m_file, line, col, offset, rule.id.value + "期望匹配" + node.value.value + " 却得到关键字" + m_file.m_text.Substring(offset, length), new ABnfRegexElement(m_factory, m_file, line, col, offset, "", node.value.regex)));
                }
                else if (length < 0)
                {
                    parent.AddChild(new ABnfErrorElement(m_factory, m_file, line, col, offset, rule.id.value + "期望匹配" + node.value.value + " 却只得到" + m_file.m_text.Substring(offset, -length), new ABnfRegexElement(m_factory, m_file, line, col, offset, "", node.value.regex)));
                    AnalysisOffset(-length, ref line, ref col, ref offset);
                    pin_offset = offset - length;
                }
                else
                {
                    parent.AddChild(new ABnfErrorElement(m_factory, m_file, line, col, offset, rule.id.value + "期望匹配" + node.value.value + " 却得到" + m_file.m_text[offset], new ABnfRegexElement(m_factory, m_file, line, col, offset, "", node.value.regex)));
                }
            }
            else
            {
                parent.AddChild(new ABnfErrorElement(m_factory, m_file, line, col, offset, rule.id.value + "期望匹配" + node.value.value + " 却得到文件结尾", new ABnfRegexElement(m_factory, m_file, line, col, offset, "", node.value.regex)));
            }
            return(false);
        }