Пример #1
0
        private void CalcPreCheck()
        {
            pre_check_value = null;
            if (node_list == null)
            {
                return;
            }
            if (node_list.Count != 1)
            {
                return;
            }
            if (node_list[0].Count < 1)
            {
                return;
            }
            if (node_list[0][0].repeat == ABnfRuleNodeRepeatType.NRT_NOT_OR_MORE ||
                node_list[0][0].repeat == ABnfRuleNodeRepeatType.NRT_ONE_OR_NOT)
            {
                return;
            }
            if (node_list[0][0].value == null)
            {
                return;
            }
            var value = node_list[0][0].value;

            if (value.type != ABnfRuleTokenType.TT_STRING &&
                value.type != ABnfRuleTokenType.TT_KEY)
            {
                return;
            }
            pre_check_value = value;
        }
Пример #2
0
 public ABnfRuleNodeInfo(ABnfRuleTokenInfo v)
 {
     value     = v;
     repeat    = ABnfRuleNodeRepeatType.NRT_NONE;
     pin       = ABnfRuleNodePinType.NPT_NONE;
     not_key   = ABnfRuleNodeNotKeyType.NNKT_NONE;
     node_list = new List <List <ABnfRuleNodeInfo> >();
 }
Пример #3
0
        // Token解析
        List <ABnfRuleTokenInfo> CalcToken()
        {
            var token_list = new List <ABnfRuleTokenInfo>();

            int line = 0;        // 当前行
            int col  = 0;        // 当前列

            ABnfRuleTokenInfo token = null;

            int index = 0;

            while (index < m_buffer.Length)
            {
                char c      = m_buffer[index];
                char next_c = '\0';
                if (index + 1 < m_buffer.Length)
                {
                    next_c = m_buffer[index + 1];
                }

                // 计算行列
                if (c == '\n')
                {
                    ++line;
                    col = 0;
                }
                else
                {
                    ++col;
                }

                // 如果在当引号内部
                if (token != null && token.type == ABnfRuleTokenType.TT_STRING)
                {
                    if (c == '\\')
                    {
                        if (next_c == '\\' || next_c == '\'')
                        {
                            token.value += next_c; ++index; ++col;
                        }
                        else if (next_c == 'a')
                        {
                            token.value += '\a'; ++index; ++col;
                        }
                        else if (next_c == 'b')
                        {
                            token.value += '\b'; ++index; ++col;
                        }
                        else if (next_c == 'f')
                        {
                            token.value += '\f'; ++index; ++col;
                        }
                        else if (next_c == 'n')
                        {
                            token.value += '\n'; ++index; ++col;
                        }
                        else if (next_c == 'r')
                        {
                            token.value += '\r'; ++index; ++col;
                        }
                        else if (next_c == 't')
                        {
                            token.value += '\t'; ++index; ++col;
                        }
                        else if (next_c == 'v')
                        {
                            token.value += '\v'; ++index; ++col;
                        }
                        else
                        {
                            token.value += c;
                        }
                    }
                    else if (c == '\'')
                    {
                        // 收集符号
                        if (!m_symbol_set.Contains(token.value))
                        {
                            m_symbol_set.Add(token.value);
                        }
                        token_list.Add(token);
                        token = null;
                    }
                    else
                    {
                        token.value += c;
                    }
                }
                else if (token != null && token.type == ABnfRuleTokenType.TT_KEY)
                {
                    if (c == '\\')
                    {
                        if (next_c == '\\' || next_c == '>')
                        {
                            token.value += next_c; ++index; ++col;
                        }
                        else if (next_c == 'a')
                        {
                            token.value += '\a'; ++index; ++col;
                        }
                        else if (next_c == 'b')
                        {
                            token.value += '\b'; ++index; ++col;
                        }
                        else if (next_c == 'f')
                        {
                            token.value += '\f'; ++index; ++col;
                        }
                        else if (next_c == 'n')
                        {
                            token.value += '\n'; ++index; ++col;
                        }
                        else if (next_c == 'r')
                        {
                            token.value += '\r'; ++index; ++col;
                        }
                        else if (next_c == 't')
                        {
                            token.value += '\t'; ++index; ++col;
                        }
                        else if (next_c == 'v')
                        {
                            token.value += '\v'; ++index; ++col;
                        }
                        else
                        {
                            token.value += c;
                        }
                    }
                    else if (c == '>')
                    {
                        // 收集关键字
                        if (!m_key_set.Contains(token.value))
                        {
                            m_key_set.Add(token.value);
                        }
                        token_list.Add(token);
                        token = null;
                    }
                    else
                    {
                        token.value += c;
                    }
                }
                else if (token != null && token.type == ABnfRuleTokenType.TT_REGEX)
                {
                    if (c == '\\')
                    {
                        if (next_c == '\\' || next_c == '"')
                        {
                            token.value += next_c; ++index; ++col;
                        }
                        else if (next_c == 'a')
                        {
                            token.value += '\a'; ++index; ++col;
                        }
                        else if (next_c == 'b')
                        {
                            token.value += '\b'; ++index; ++col;
                        }
                        else if (next_c == 'f')
                        {
                            token.value += '\f'; ++index; ++col;
                        }
                        else if (next_c == 'n')
                        {
                            token.value += '\n'; ++index; ++col;
                        }
                        else if (next_c == 'r')
                        {
                            token.value += '\r'; ++index; ++col;
                        }
                        else if (next_c == 't')
                        {
                            token.value += '\t'; ++index; ++col;
                        }
                        else if (next_c == 'v')
                        {
                            token.value += '\v'; ++index; ++col;
                        }
                        else
                        {
                            token.value += c;
                        }
                    }
                    else if (c == '"')
                    {
                        token_list.Add(token);
                        token = null;
                    }
                    else
                    {
                        token.value += c;
                    }
                }
                else if (token != null && token.type == ABnfRuleTokenType.TT_LINE_COMMENT)
                {
                    if (c == '\r')
                    {
                        if (next_c == '\n')
                        {
                            ++index;
                            ++line;
                            col = 0;
                            token_list.Add(token);
                            token = null;
                        }
                        else
                        {
                            token.value += c;
                        }
                    }
                    else if (c == '\n')
                    {
                        token_list.Add(token);
                        token = null;
                    }
                    else
                    {
                        token.value += c;
                    }
                }
                else if (token != null && token.type == ABnfRuleTokenType.TT_BLOCK_COMMENT)
                {
                    if (c == '*')
                    {
                        if (next_c == '/')
                        {
                            ++index;
                            ++col;
                            token_list.Add(token);
                            token = null;
                        }
                        else
                        {
                            token.value += c;
                        }
                    }
                    else
                    {
                        token.value += c;
                    }
                }
                else
                {
                    if (c == '\'')
                    {
                        if (token != null)
                        {
                            token_list.Add(token);
                        }
                        token      = new ABnfRuleTokenInfo(ABnfRuleTokenType.TT_STRING);
                        token.line = line;
                        token.col  = col;
                    }
                    else if (c == '<')
                    {
                        if (token != null)
                        {
                            token_list.Add(token);
                        }
                        token      = new ABnfRuleTokenInfo(ABnfRuleTokenType.TT_KEY);
                        token.line = line;
                        token.col  = col;
                    }
                    else if (c == '"')
                    {
                        if (token != null)
                        {
                            token_list.Add(token);
                        }
                        token      = new ABnfRuleTokenInfo(ABnfRuleTokenType.TT_REGEX);
                        token.line = line;
                        token.col  = col;
                    }
                    else if (c == '/' && next_c == '/')
                    {
                        ++index;
                        ++col;
                        if (token != null)
                        {
                            token_list.Add(token);
                        }
                        token      = new ABnfRuleTokenInfo(ABnfRuleTokenType.TT_LINE_COMMENT);
                        token.line = line;
                        token.col  = col;
                    }
                    else if (c == '/' && next_c == '*')
                    {
                        ++index;
                        ++col;
                        if (token != null)
                        {
                            token_list.Add(token);
                        }
                        token      = new ABnfRuleTokenInfo(ABnfRuleTokenType.TT_BLOCK_COMMENT);
                        token.line = line;
                        token.col  = col;
                    }
                    else if (c == '=' || c == '@' || c == '#' || c == ':' ||
                             c == '*' || c == '?' || c == '+' ||
                             c == '|' || c == ';' ||
                             c == '(' || c == ')')
                    {
                        if (token != null)
                        {
                            token_list.Add(token);
                        }

                        token        = new ABnfRuleTokenInfo(ABnfRuleTokenType.TT_SYMBOL);
                        token.value += c;
                        token.line   = line;
                        token.col    = col;
                        token_list.Add(token);

                        token = null;
                    }
                    else if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
                    {
                        if (token != null)
                        {
                            token_list.Add(token);
                        }

                        token = null;
                    }
                    else
                    {
                        if (token == null)
                        {
                            token      = new ABnfRuleTokenInfo(ABnfRuleTokenType.TT_ID);
                            token.line = line;
                            token.col  = col;
                        }
                        token.value += c;
                    }
                }

                ++index;
            }

            if (token != null)
            {
                token_list.Add(token);
            }

            return(token_list);
        }
Пример #4
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);
        }
Пример #5
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);
        }