Beispiel #1
0
        // 行注释匹配
        bool AnalysisABnfCommentMatch(ABnfRuleInfo rule, ABnfNodeElement parent, bool not_key
                                      , ref int line, ref int col, ref int offset)
        {
            // 如果是注释,那么直接返回
            if (m_line_comment == rule || m_block_comment == rule)
            {
                return(true);
            }

            // 循环匹配,直至行注释和多行注释一起匹配失败
            while (true)
            {
                bool match      = false;
                int  pin_offset = -1;
                if (m_line_comment != null)
                {
                    if (!m_line_comment_skip.Contains(offset))
                    {
                        if (AnalysisABnfRuleMatch(m_line_comment, parent, not_key
                                                  , ref line, ref col, ref offset
                                                  , ref pin_offset, true))
                        {
                            match = true;
                        }
                        else
                        {
                            m_line_comment_skip.Add(offset);
                        }
                    }
                }

                if (m_block_comment != null)
                {
                    if (!m_block_comment_skip.Contains(offset))
                    {
                        if (AnalysisABnfRuleMatch(m_block_comment, parent, not_key
                                                  , ref line, ref col, ref offset
                                                  , ref pin_offset, true))
                        {
                            match = true;
                        }
                        else
                        {
                            m_block_comment_skip.Add(offset);
                        }
                    }
                }

                if (!match)
                {
                    return(true);
                }
            }
        }
Beispiel #2
0
 // 初始化参数
 public void Clear()
 {
     m_file    = null;
     m_factory = null;
     m_regex_skip.Clear();
     m_line_comment_skip.Clear();
     m_block_comment_skip.Clear();
     m_stat          = null;
     m_root          = null;
     m_line_comment  = null;
     m_block_comment = null;
     m_rule.Clear();
     m_symbol_check.Clear();
 }
Beispiel #3
0
        // 加载文法
        public string Load(string buffer, ABnfFactory factory)
        {
            try
            {
                // 清理
                Clear();

                // 设置节点工厂
                m_factory = factory;
                if (m_factory == null)
                {
                    return("m_factory == null");
                }

                // 保存字符串内容
                m_rule.Load(buffer);

                // 保存特殊的规则
                m_root          = m_rule.FindRuleInfo("Root");
                m_line_comment  = m_rule.FindRuleInfo("LineComment");
                m_block_comment = m_rule.FindRuleInfo("BlockComment");

                var symbol_set = m_rule.GetSymbolSet();
                foreach (var symbol in symbol_set)
                {
                    foreach (var symbol_check in symbol_set)
                    {
                        if (symbol_check.StartsWith(symbol) &&
                            symbol_check.Length > symbol.Length)
                        {
                            if (!m_symbol_check.TryGetValue(symbol, out HashSet <char> set))
                            {
                                set = new HashSet <char>();
                                m_symbol_check.Add(symbol, set);
                            }
                            set.Add(symbol_check[symbol.Length]);
                        }
                    }
                }
            }
            catch (System.Exception e)
            {
                Clear();
                return(e.Message);
            }

            return(null);
        }
Beispiel #4
0
        // 加载文法
        public string Load(string buffer)
        {
            try
            {
                // 清理
                Clear();

                // 保存字符串内容
                m_buffer = buffer;

                // 解析token
                List <ABnfRuleTokenInfo> token_list = CalcToken();

                // 对token列表进行语法分析
                int offset = 0;
                while (offset < token_list.Count)
                {
                    // 解析规则
                    ABnfRuleInfo rule = CalcABnfRule(token_list, ref offset);
                    if (m_rule_map.ContainsKey(rule.id.value))
                    {
                        throw new System.Exception("规则名重复定义:" + rule.id.value);
                    }
                    m_rule_map[rule.id.value] = rule;
                }

                foreach (var pair in m_rule_map)
                {
                    pair.Value.CalcNextChar();
                }
            }
            catch (System.Exception e)
            {
                Clear();
                return(e.Message);
            }

            return(null);
        }
Beispiel #5
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 #6
0
        // 解析规则语句
        ABnfRuleInfo CalcABnfRule(List <ABnfRuleTokenInfo> token_list, ref int offset)
        {
            ABnfRuleInfo rule = new ABnfRuleInfo(this);

            // 跳过注释
            while (offset < token_list.Count &&
                   (token_list[offset].type == ABnfRuleTokenType.TT_LINE_COMMENT ||
                    token_list[offset].type == ABnfRuleTokenType.TT_BLOCK_COMMENT))
            {
                ++offset;
            }

            // 处理ID
            if (offset >= token_list.Count)
            {
                throw new System.Exception("最后一条规则不完整");
            }

            if (token_list[offset].type != ABnfRuleTokenType.TT_ID)
            {
                throw new System.Exception("行:" + token_list[offset].line + "列:" + token_list[offset].col
                                           + "期望是规则名 却得到:" + token_list[offset].value);
            }

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

            rule.id = token_list[offset];
            ++offset;

            // 处理冒号
            if (offset >= token_list.Count)
            {
                throw new System.Exception("最后一条规则不完整");
            }

            if (token_list[offset].type == ABnfRuleTokenType.TT_SYMBOL && token_list[offset].value == ":")
            {
                ++offset;
                // 处理预测正则表达式
                if (offset >= token_list.Count)
                {
                    throw new System.Exception("最后一条规则不完整");
                }

                if (token_list[offset].type != ABnfRuleTokenType.TT_REGEX)
                {
                    throw new System.Exception("行:" + token_list[offset].line + "列:" + token_list[offset].col
                                               + "期望是预测正则表达式 却得到:" + token_list[offset].value);
                }

                rule.prediction = token_list[offset];
                ++offset;

                // 处理预测pin
                if (offset < token_list.Count &&
                    token_list[offset].type == ABnfRuleTokenType.TT_SYMBOL &&
                    token_list[offset].value == "@")
                {
                    rule.prediction_pin = ABnfRuleNodePinType.NPT_TRUE;
                    ++offset;
                }
            }

            // 处理等号
            if (offset >= token_list.Count)
            {
                throw new System.Exception("最后一条规则不完整");
            }

            if (token_list[offset].type != ABnfRuleTokenType.TT_SYMBOL && token_list[offset].value != "=")
            {
                throw new System.Exception("行:" + token_list[offset].line + "列:" + token_list[offset].col
                                           + "期望是= 却得到:" + token_list[offset].value);
            }
            rule.assign = token_list[offset];
            ++offset;

            // 获取规则内容
            rule.node = CalcABnfNode(token_list, ref offset);
            if (rule.node == null || rule.node.node_list.Count == 0)
            {
                throw new System.Exception("行:" + rule.id.line + "列:" + rule.id.col
                                           + "规则内容是空的");
            }

            // 如果遇到分号表示结束
            if (offset >= token_list.Count)
            {
                throw new System.Exception("最后一条规则不完整");
            }

            if (token_list[offset].type != ABnfRuleTokenType.TT_SYMBOL || token_list[offset].value != ";")
            {
                throw new System.Exception("行:" + token_list[offset].line + "列:" + token_list[offset].col
                                           + "期望是; 却得到:" + token_list[offset].value);
            }
            ++offset;

            return(rule);
        }
Beispiel #7
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 #8
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 #9
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 #10
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);
        }
Beispiel #11
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 #12
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 #13
0
        // 解析规则语句
        private ABnfRuleInfo CalcABnfRule(List <ABnfRuleTokenInfo> token_list, ref int offset)
        {
            ABnfRuleInfo rule = new ABnfRuleInfo(this);

            // 跳过注释
            while (offset < token_list.Count &&
                   (token_list[offset].type == ABnfRuleTokenType.TT_LINE_COMMENT ||
                    token_list[offset].type == ABnfRuleTokenType.TT_BLOCK_COMMENT))
            {
                ++offset;
            }

            // 处理ID
            if (offset >= token_list.Count)
            {
                throw new System.Exception("The last rule is incomplete");
            }

            if (token_list[offset].type != ABnfRuleTokenType.TT_ID)
            {
                throw new System.Exception("Row:" + token_list[offset].line + "Col:" + token_list[offset].col
                                           + "Expected to be the rule name but got :" + token_list[offset].value);
            }

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

            rule.id = token_list[offset];
            ++offset;

            // 处理冒号
            if (offset >= token_list.Count)
            {
                throw new System.Exception("The last rule is incomplete");
            }

            if (token_list[offset].type == ABnfRuleTokenType.TT_SYMBOL && token_list[offset].value == ":")
            {
                ++offset;
                // 处理预测正则表达式
                if (offset >= token_list.Count)
                {
                    throw new System.Exception("The last rule is incomplete");
                }

                if (token_list[offset].type != ABnfRuleTokenType.TT_REGEX)
                {
                    throw new System.Exception("Line: " + token_list[offset].line + ", Col: " + token_list[offset].col
                                               + " The expectation is to predict the regular expression but got: " + token_list[offset].value);
                }

                rule.prediction = token_list[offset];
                ++offset;

                // 处理预测pin
                if (offset < token_list.Count &&
                    token_list[offset].type == ABnfRuleTokenType.TT_SYMBOL &&
                    token_list[offset].value == "@")
                {
                    rule.prediction_pin = ABnfRuleNodePinType.NPT_TRUE;
                    ++offset;
                }
            }

            // 处理等号
            if (offset >= token_list.Count)
            {
                throw new System.Exception("The last rule is incomplete");
            }

            if (token_list[offset].type != ABnfRuleTokenType.TT_SYMBOL && token_list[offset].value != "=")
            {
                throw new System.Exception("Row: " + token_list[offset].line + ", Col: " + token_list[offset].col
                                           + " Expected = but got:" + token_list[offset].value);
            }
            rule.assign = token_list[offset];
            ++offset;

            // 获取规则内容
            rule.node = CalcABnfNode(token_list, ref offset);
            if (rule.node == null || rule.node.node_list.Count == 0)
            {
                throw new System.Exception("Line: " + rule.id.line + ", Col: " + rule.id.col
                                           + " Rule content is empty");
            }

            // 如果遇到分号表示结束
            if (offset >= token_list.Count)
            {
                throw new System.Exception("The last rule is incomplete");
            }

            if (token_list[offset].type != ABnfRuleTokenType.TT_SYMBOL || token_list[offset].value != ";")
            {
                throw new System.Exception("Line: " + token_list[offset].line + ", Col: " + token_list[offset].col
                                           + " Expected ; but got: " + token_list[offset].value);
            }
            ++offset;

            return(rule);
        }