Beispiel #1
0
        bool AnalysisABnfNodeMore(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)
        {
            while (offset < m_file.m_text.Length)
            {
                int temp_pin_offset = -1;
                if (!AnalysisABnfNodeMatch(rule, node, parent, not_key
                                           , ref line, ref col, ref offset
                                           , ref temp_pin_offset, ignore_error))
                {
                    // 如果匹配内部有pin,那么也要对外标记为pin
                    // 并且认为匹配失败
                    if (temp_pin_offset >= 0)
                    {
                        // 这里特意使用offset作为pin
                        pin_offset = offset;
                        return(false);
                    }

                    // 内部没有pin,可以标记为当前匹配成功,放弃失败的部分
                    return(true);
                }

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

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

            return(true);
        }
Beispiel #2
0
        // 解析规则节点
        ABnfRuleNodeInfo CalcABnfNode(List <ABnfRuleTokenInfo> token_list, ref int offset)
        {
            ABnfRuleNodeInfo node = new ABnfRuleNodeInfo();

            while (offset < token_list.Count)
            {
                ABnfRuleTokenInfo token = token_list[offset];

                // 如果是注释,那么就跳过
                if (token.type == ABnfRuleTokenType.TT_LINE_COMMENT || token.type == ABnfRuleTokenType.TT_BLOCK_COMMENT)
                {
                    ++offset;
                    continue;
                }

                // 检查ID
                if (token.type == ABnfRuleTokenType.TT_ID)
                {
                    // 正则表达式匹配
                    if (!Regex.IsMatch(token.value, "^[_a-zA-Z][_a-zA-Z0-9]*$"))
                    {
                        throw new System.Exception("行:" + token.line + "列:" + token.col
                                                   + "ID 必须以小写字母、大写字母、数字、下划线,并且不能以数字开头,但是得到是:" + token.value);
                    }

                    if (node.node_list.Count == 0)
                    {
                        node.node_list.Add(new List <ABnfRuleNodeInfo>());
                    }
                    node.node_list[node.node_list.Count - 1].Add(new ABnfRuleNodeInfo(token));

                    ++offset;
                    continue;
                }

                // 检查字符串
                if (token.type == ABnfRuleTokenType.TT_STRING ||
                    token.type == ABnfRuleTokenType.TT_KEY ||
                    token.type == ABnfRuleTokenType.TT_REGEX)
                {
                    if (node.node_list.Count == 0)
                    {
                        node.node_list.Add(new List <ABnfRuleNodeInfo>());
                    }
                    node.node_list[node.node_list.Count - 1].Add(new ABnfRuleNodeInfo(token));

                    ++offset;
                    continue;
                }

                // 最后检查符号
                if (token.type == ABnfRuleTokenType.TT_SYMBOL)
                {
                    if (token.value == "(")
                    {
                        ++offset;

                        if (node.node_list.Count == 0)
                        {
                            node.node_list.Add(new List <ABnfRuleNodeInfo>());
                        }
                        node.node_list[node.node_list.Count - 1].Add(CalcABnfNode(token_list, ref offset));

                        if (offset >= token_list.Count || token_list[offset].value != ")")
                        {
                            throw new System.Exception("行:" + token.line + "列:" + token.col
                                                       + "期望是),但得到的是:" + token.value);
                        }

                        ++offset;
                        continue;
                    }
                    else if (token.value == "*")
                    {
                        if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0)
                        {
                            throw new System.Exception("行:" + token.line + "列:" + token.col
                                                       + "符号*前面没有定义内容");
                        }

                        var node_list = node.node_list[node.node_list.Count - 1];
                        if (node_list[node_list.Count - 1].repeat != ABnfRuleNodeRepeatType.NRT_NONE)
                        {
                            throw new System.Exception("行:" + token.line + "列:" + token.col
                                                       + "符号*前面已经定义了重复规则");
                        }

                        node_list[node_list.Count - 1].repeat = ABnfRuleNodeRepeatType.NRT_NOT_OR_MORE;

                        ++offset;
                        continue;
                    }
                    else if (token.value == "+")
                    {
                        if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0)
                        {
                            throw new System.Exception("行:" + token.line + "列:" + token.col
                                                       + "符号+前面没有定义内容");
                        }

                        var node_list = node.node_list[node.node_list.Count - 1];
                        if (node_list[node_list.Count - 1].repeat != ABnfRuleNodeRepeatType.NRT_NONE)
                        {
                            throw new System.Exception("行:" + token.line + "列:" + token.col
                                                       + "符号+前面已经定义了重复规则");
                        }

                        node_list[node_list.Count - 1].repeat = ABnfRuleNodeRepeatType.NRT_AT_LEAST_ONE;

                        ++offset;
                        continue;
                    }
                    else if (token.value == "?")
                    {
                        if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0)
                        {
                            throw new System.Exception("行:" + token.line + "列:" + token.col
                                                       + "符号?前面没有定义内容");
                        }

                        var node_list = node.node_list[node.node_list.Count - 1];
                        if (node_list[node_list.Count - 1].repeat != ABnfRuleNodeRepeatType.NRT_NONE)
                        {
                            throw new System.Exception("行:" + token.line + "列:" + token.col
                                                       + "符号?前面已经定义了重复规则");
                        }

                        node_list[node_list.Count - 1].repeat = ABnfRuleNodeRepeatType.NRT_ONE_OR_NOT;

                        ++offset;
                        continue;
                    }
                    else if (token.value == "@")
                    {
                        if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0)
                        {
                            throw new System.Exception("行:" + token.line + "列:" + token.col
                                                       + "符号@前面没有定义内容");
                        }

                        var node_list = node.node_list[node.node_list.Count - 1];
                        if (node_list[node_list.Count - 1].pin != ABnfRuleNodePinType.NPT_NONE)
                        {
                            throw new System.Exception("行:" + token.line + "列:" + token.col
                                                       + "符号@前面已经定义了pin规则");
                        }

                        node_list[node_list.Count - 1].pin = ABnfRuleNodePinType.NPT_TRUE;

                        ++offset;
                        continue;
                    }
                    else if (token.value == "#")
                    {
                        if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0)
                        {
                            throw new System.Exception("行:" + token.line + "列:" + token.col
                                                       + "符号#前面没有定义内容");
                        }

                        var node_list = node.node_list[node.node_list.Count - 1];
                        if (node_list[node_list.Count - 1].not_key != ABnfRuleNodeNotKeyType.NNKT_NONE)
                        {
                            throw new System.Exception("行:" + token.line + "列:" + token.col
                                                       + "符号#前面已经定义了非key规则");
                        }

                        node_list[node_list.Count - 1].not_key = ABnfRuleNodeNotKeyType.NNKT_TRUE;

                        ++offset;
                        continue;
                    }
                    else if (token.value == "|")
                    {
                        if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0)
                        {
                            throw new System.Exception("行:" + token.line + "列:" + token.col
                                                       + "符号|前面没有定义内容");
                        }


                        if (offset + 1 >= token_list.Count &&
                            token_list[offset + 1].type == ABnfRuleTokenType.TT_SYMBOL &&
                            token_list[offset + 1].value == ";")
                        {
                            throw new System.Exception("行:" + token.line + "列:" + token.col
                                                       + "符号|后面没有定义内容");
                        }

                        node.node_list.Add(new List <ABnfRuleNodeInfo>());

                        ++offset;
                        continue;
                    }
                    else if (token.value == ";" || token.value == ")")
                    {
                        break;
                    }
                    else
                    {
                        throw new System.Exception("行:" + token.line + "列:" + token.col
                                                   + "当前不能处理:" + token.value);
                    }
                }

                throw new System.Exception("行:" + token.line + "列:" + token.col
                                           + "未知的token类型:" + token.value);
            }

            return(node);
        }
Beispiel #3
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);
        }
Beispiel #4
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);
        }
Beispiel #5
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);
        }
Beispiel #6
0
        // 分析规则语句
        bool AnalysisABnfNode(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.repeat == ABnfRuleNodeRepeatType.NRT_NONE || node.repeat == ABnfRuleNodeRepeatType.NRT_ONE)
            {
                // 匹配第一个
                int temp_pin_offset = -1;
                if (!AnalysisABnfNodeMatch(rule, node, parent, not_key
                                           , ref line, ref col, ref offset
                                           , ref temp_pin_offset, ignore_error))
                {
                    // 如果匹配内部有pin,那么也要对外标记为pin
                    if (temp_pin_offset >= 0)
                    {
                        pin_offset = temp_pin_offset;
                    }

                    // 返回匹配失败
                    return(false);
                }

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

                return(true);
            }

            // 处理 (至少一个)
            if (node.repeat == ABnfRuleNodeRepeatType.NRT_AT_LEAST_ONE)
            {
                // 匹配第一个
                int temp_pin_offset = -1;
                if (!AnalysisABnfNodeMatch(rule, node, parent, not_key
                                           , ref line, ref col, ref offset
                                           , ref temp_pin_offset, ignore_error))
                {
                    // 如果匹配内部有pin,那么也要对外标记为pin
                    if (temp_pin_offset >= 0)
                    {
                        pin_offset = temp_pin_offset;
                    }

                    // 返回匹配失败
                    return(false);
                }

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

                // 匹配剩下的
                return(AnalysisABnfNodeMore(rule, node, parent, not_key
                                            , ref line, ref col, ref offset
                                            , ref pin_offset, true));
            }

            // 处理 (没有或者一个)
            if (node.repeat == ABnfRuleNodeRepeatType.NRT_ONE_OR_NOT)
            {
                int temp_pin_offset = -1;
                if (!AnalysisABnfNodeMatch(rule, node, parent, not_key
                                           , ref line, ref col, ref offset
                                           , ref temp_pin_offset, true))
                {
                    // 如果匹配内部有pin,那么也要对外标记为pin
                    // 并且认为匹配失败
                    if (temp_pin_offset >= 0)
                    {
                        pin_offset = temp_pin_offset;
                        return(false);
                    }

                    // 内部没有pin,可以标记为当前匹配成功,放弃失败的部分
                    return(true);
                }

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

                return(true);
            }

            // 处理 (没有或者任意多个)
            if (node.repeat == ABnfRuleNodeRepeatType.NRT_NOT_OR_MORE)
            {
                return(AnalysisABnfNodeMore(rule, node, parent, not_key
                                            , ref line, ref col, ref offset
                                            , ref pin_offset, true));
            }

            // 这里一般不会发生
            return(false);
        }
Beispiel #7
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);
        }
Beispiel #8
0
        // 解析规则节点
        private ABnfRuleNodeInfo CalcABnfNode(List <ABnfRuleTokenInfo> token_list, ref int offset)
        {
            ABnfRuleNodeInfo node = new ABnfRuleNodeInfo();

            while (offset < token_list.Count)
            {
                ABnfRuleTokenInfo token = token_list[offset];

                // 如果是注释,那么就跳过
                if (token.type == ABnfRuleTokenType.TT_LINE_COMMENT || token.type == ABnfRuleTokenType.TT_BLOCK_COMMENT)
                {
                    ++offset;
                    continue;
                }

                // 检查ID
                if (token.type == ABnfRuleTokenType.TT_ID)
                {
                    // 正则表达式匹配
                    if (!Regex.IsMatch(token.value, "^[_a-zA-Z][_a-zA-Z0-9]*$"))
                    {
                        throw new System.Exception("Line: " + token.line + ", Col: " + token.col
                                                   + "ID must start with lowercase letters, uppercase letters, numbers, and underscores, and cannot start with a number, but the result is: " + token.value);
                    }

                    if (node.node_list.Count == 0)
                    {
                        node.node_list.Add(new List <ABnfRuleNodeInfo>());
                    }
                    node.node_list[node.node_list.Count - 1].Add(new ABnfRuleNodeInfo(token));

                    ++offset;
                    continue;
                }

                // 检查字符串
                if (token.type == ABnfRuleTokenType.TT_STRING ||
                    token.type == ABnfRuleTokenType.TT_KEY ||
                    token.type == ABnfRuleTokenType.TT_REGEX)
                {
                    if (node.node_list.Count == 0)
                    {
                        node.node_list.Add(new List <ABnfRuleNodeInfo>());
                    }
                    node.node_list[node.node_list.Count - 1].Add(new ABnfRuleNodeInfo(token));

                    ++offset;
                    continue;
                }

                // 最后检查Left hand of
                if (token.type == ABnfRuleTokenType.TT_SYMBOL)
                {
                    if (token.value == "(")
                    {
                        ++offset;

                        if (node.node_list.Count == 0)
                        {
                            node.node_list.Add(new List <ABnfRuleNodeInfo>());
                        }
                        node.node_list[node.node_list.Count - 1].Add(CalcABnfNode(token_list, ref offset));

                        if (offset >= token_list.Count || token_list[offset].value != ")")
                        {
                            throw new System.Exception("Line: " + token.line + ", Col: " + token.col
                                                       + "The expectation is), but what I get is: " + token.value);
                        }

                        ++offset;
                        continue;
                    }
                    else if (token.value == "*")
                    {
                        if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0)
                        {
                            throw new System.Exception("Line: " + token.line + ", Col: " + token.col
                                                       + "No content defined in front of the symbol * ");
                        }

                        var node_list = node.node_list[node.node_list.Count - 1];
                        if (node_list[node_list.Count - 1].repeat != ABnfRuleNodeRepeatType.NRT_NONE)
                        {
                            throw new System.Exception("Line: " + token.line + ", Col: " + token.col
                                                       + "The symbol * has previously defined the repetition rule ");
                        }

                        node_list[node_list.Count - 1].repeat = ABnfRuleNodeRepeatType.NRT_NOT_OR_MORE;

                        ++offset;
                        continue;
                    }
                    else if (token.value == "+")
                    {
                        if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0)
                        {
                            throw new System.Exception("Line: " + token.line + ", Col: " + token.col
                                                       + "Symbol + no content defined in front ");
                        }

                        var node_list = node.node_list[node.node_list.Count - 1];
                        if (node_list[node_list.Count - 1].repeat != ABnfRuleNodeRepeatType.NRT_NONE)
                        {
                            throw new System.Exception("Line: " + token.line + ", Col: " + token.col
                                                       + "Symbol + The repetition rule has been defined before ");
                        }

                        node_list[node_list.Count - 1].repeat = ABnfRuleNodeRepeatType.NRT_AT_LEAST_ONE;

                        ++offset;
                        continue;
                    }
                    else if (token.value == "?")
                    {
                        if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0)
                        {
                            throw new System.Exception("Line: " + token.line + ", Col: " + token.col
                                                       + "Symbol ? No content defined in front ");
                        }

                        var node_list = node.node_list[node.node_list.Count - 1];
                        if (node_list[node_list.Count - 1].repeat != ABnfRuleNodeRepeatType.NRT_NONE)
                        {
                            throw new System.Exception("Line: " + token.line + ", Col: " + token.col
                                                       + "Symbol ? has been defined previously");
                        }

                        node_list[node_list.Count - 1].repeat = ABnfRuleNodeRepeatType.NRT_ONE_OR_NOT;

                        ++offset;
                        continue;
                    }
                    else if (token.value == "@")
                    {
                        if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0)
                        {
                            throw new System.Exception("Line: " + token.line + ", Col: " + token.col
                                                       + "Left hand of @ is missing");
                        }

                        var node_list = node.node_list[node.node_list.Count - 1];
                        if (node_list[node_list.Count - 1].pin != ABnfRuleNodePinType.NPT_NONE)
                        {
                            throw new System.Exception("Line: " + token.line + ", Col: " + token.col
                                                       + "Symbol @ is defined after the pin rule");
                        }

                        node_list[node_list.Count - 1].pin = ABnfRuleNodePinType.NPT_TRUE;

                        ++offset;
                        continue;
                    }
                    else if (token.value == "#")
                    {
                        if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0)
                        {
                            throw new System.Exception("Line: " + token.line + ", Col: " + token.col
                                                       + "Left hand of # is missing");
                        }

                        var node_list = node.node_list[node.node_list.Count - 1];
                        if (node_list[node_list.Count - 1].not_key != ABnfRuleNodeNotKeyType.NNKT_NONE)
                        {
                            throw new System.Exception("Line: " + token.line + ", Col: " + token.col
                                                       + "Left hand of # has been defined previously");
                        }

                        node_list[node_list.Count - 1].not_key = ABnfRuleNodeNotKeyType.NNKT_TRUE;

                        ++offset;
                        continue;
                    }
                    else if (token.value == "|")
                    {
                        if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0)
                        {
                            throw new System.Exception("Line: " + token.line + ", Col: " + token.col
                                                       + "Left hand of | is missing");
                        }

                        if (offset + 1 >= token_list.Count &&
                            token_list[offset + 1].type == ABnfRuleTokenType.TT_SYMBOL &&
                            token_list[offset + 1].value == ";")
                        {
                            throw new System.Exception("Line: " + token.line + ", Col: " + token.col
                                                       + "Right hand of | is missing");
                        }

                        node.node_list.Add(new List <ABnfRuleNodeInfo>());

                        ++offset;
                        continue;
                    }
                    else if (token.value == ";" || token.value == ")")
                    {
                        break;
                    }
                    else
                    {
                        throw new System.Exception("Line: " + token.line + ", Col: " + token.col
                                                   + "Unsupported:" + token.value);
                    }
                }

                throw new System.Exception("Line: " + token.line + ", Col: " + token.col
                                           + "Unknown token type:" + token.value);
            }

            return(node);
        }