예제 #1
0
        // 函数调用参数提示
        public void QuerySignatureHelp(int offset)
        {
            // 获取元素
            var element = GetException(offset);

            if (element == null)
            {
                return;
            }

            // 获取类型
            ABnfNodeElement node = element as ABnfNodeElement;

            if (node == null)
            {
                node = element.GetParent();
            }
            if (node == null)
            {
                return;
            }

            var info = node.GetReference().QuerySignatureHelp(out int start, out int length);

            if (info == null)
            {
                return;
            }
            if (info.param_list.Count == 0)
            {
                return;
            }

            Application.Current.Dispatcher.Invoke(() =>
            {
                if (m_view.TextBuffer.Properties.TryGetProperty(nameof(ALanguageSignatureHelpSource), out ALanguageSignatureHelpSource source))
                {
                    source.RefreshSignatureHelp(m_view, start, length, info);
                    if (m_view.Properties.TryGetProperty(nameof(ALanguageController), out ALanguageController controller))
                    {
                        controller.StartSignatureHelp(start);
                    }
                }
                else
                {
                    if (m_view.Properties.TryGetProperty(nameof(ALanguageController), out ALanguageController controller))
                    {
                        controller.StartSignatureHelp(start);
                    }
                    if (m_view.TextBuffer.Properties.TryGetProperty(nameof(ALanguageSignatureHelpSource), out source))
                    {
                        source.RefreshSignatureHelp(m_view, start, length, info);
                    }
                }
            });
        }
예제 #2
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);
                }
            }
        }
예제 #3
0
        // 拾取高亮
        public void PeekHighlightWord(int offset, long version)
        {
            ABnfElement element = GetException(offset);

            if (element == null)
            {
                return;
            }
            if (element is ABnfErrorElement)
            {
                return;
            }

            var    target = element;
            string value  = element.GetElementText();

            if (!m_left_pairs.ContainsKey(value) && !m_right_pairs.ContainsKey(value))
            {
                target = null;
            }

            ABnfNodeElement node = element as ABnfNodeElement;

            if (node == null)
            {
                node = element.GetParent();
            }
            if (node == null)
            {
                return;
            }

            if (node.GetReference().PeekHighlightWord())
            {
                target = node;
            }

            if (target == null)
            {
                return;
            }

            var list = new List <ALanguageHighlightWordInfo>();

            QueryHighlightWordTag(element, list);
            Application.Current.Dispatcher.Invoke(() =>
            {
                if (m_view.Properties.TryGetProperty(nameof(ALanguageHighlightWordTagger), out ALanguageHighlightWordTagger tagger))
                {
                    tagger.Refresh(version, list);
                }
            });
        }
예제 #4
0
        public ABnfNodeElement CreateNodeElement(int line, int col, int offset, string type)
        {
            if (m_stat != null)
            {
                m_stat.CreateNode(type);
            }
            var node = m_factory.CreateNodeElement(m_file, line, col, offset, type);

            if (node == null)
            {
                node = new ABnfNodeElement(m_factory, m_file, line, col, offset, type);
            }
            return(node);
        }
예제 #5
0
        // 跳转
        public void GotoDefinition(int offset)
        {
            var element = GetException(offset);

            if (element == null)
            {
                return;
            }
            if (element is ABnfErrorElement)
            {
                return;
            }

            ABnfNodeElement node = element as ABnfNodeElement;

            if (node == null)
            {
                node = element.GetParent();
            }
            if (node == null)
            {
                return;
            }

            var target = node.GetReference().GotoDefinition();

            if (target == null)
            {
                return;
            }

            string full_path = target.GetFullPath();
            int    start     = target.GetStart();
            int    length    = target.GetLength();

            Application.Current.Dispatcher.Invoke(() =>
            {
                if (m_view.Properties.TryGetProperty(nameof(UIViewItem), out UIViewItem info))
                {
                    info.JumpToView(full_path, start, length);
                }
            });
        }
예제 #6
0
        public void CollectIndex(ABnfNodeElement node)
        {
            if (node.GetNodeType() == "Id")
            {
                var value = node.GetElementText();
                HashSet <ABnfNodeElement> set;
                if (!m_index.TryGetValue(value, out set))
                {
                    set = new HashSet <ABnfNodeElement>();
                    m_index.Add(value, set);
                }
                set.Add(node as ABnfNodeElement);
            }

            foreach (var child in node.GetChilds())
            {
                if (child is ABnfNodeElement)
                {
                    CollectIndex(child as ABnfNodeElement);
                }
            }
        }
예제 #7
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);
        }
예제 #8
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);
        }
예제 #9
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);
        }
예제 #10
0
        private bool QueryCompletionImpl(string input, int offset, out int start, out int length, out List <ALanguageCompletionInfo> list)
        {
            list   = new List <ALanguageCompletionInfo>();
            start  = offset;
            length = 1;

            // 获取元素
            var element = GetException(offset);

            if (element == null)
            {
                var new_input = m_factory.ShowKeyWordCompletion(input, element);
                if (new_input != null)
                {
                    m_abnf.QueryKeyWordCompletion(new_input, list);
                }
                return(true);
            }

            if (element is ABnfErrorElement)
            {
                var new_input = m_factory.ShowKeyWordCompletion(input, element);
                if (new_input != null)
                {
                    m_abnf.QueryKeyWordCompletion(new_input, list);
                }
                return(true);
            }

            if (element.GetLength() != 0)
            {
                start  = element.GetStart();
                length = element.GetLength();
            }

            ABnfNodeElement node = element as ABnfNodeElement;

            if (node == null)
            {
                node = element.GetParent();
            }
            if (node == null)
            {
                var new_input = m_factory.ShowKeyWordCompletion(input, node);
                if (new_input != null)
                {
                    m_abnf.QueryKeyWordCompletion(new_input, list);
                }
                return(true);
            }

            {
                var new_input = m_factory.ShowKeyWordCompletion(input, node);
                if (new_input != null)
                {
                    m_abnf.QueryKeyWordCompletion(new_input, list);
                }
            }
            var result = node.GetReference().QueryCompletion(offset, list);

            if (list.Count == 0)
            {
                return(result);
            }

            list.Sort(delegate(ALanguageCompletionInfo a, ALanguageCompletionInfo b) { return(a.display.CompareTo(b.display)); });
            return(true);
        }
예제 #11
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);
        }
예제 #12
0
        // 生成文件
        public override bool CompileDocument()
        {
            if (HasError())
            {
                MessageBox.Show("请修正错误后再进行编译");
                return(true);
            }

            var project_info = GetProjectInfo();

            if (project_info == null)
            {
                MessageBox.Show("请将当前文件放入工程后再进行编译");
                return(true);
            }

            string language_name = Path.GetFileNameWithoutExtension(GetFullPath());

            string path = project_info.GetProjectPath();

            if (!path.EndsWith("/") && !path.EndsWith("\\"))
            {
                path += "\\";
            }
            path += "Generate";
            if (Directory.Exists(path))
            {
                DeleteFolder(path);
            }
            if (Directory.CreateDirectory(path) == null)
            {
                MessageBox.Show("目标目录创建失败:" + path);
                return(true);
            }

            string add_new_buffer = "";

            foreach (var rule in m_rule)
            {
                ABnfElement element = null;
                foreach (var e in rule.Value)
                {
                    if (element != null)
                    {
                        MessageBox.Show(rule.Key + " 的元素对象有" + rule.Value.Count + "个");
                        return(true);
                    }

                    element = e;
                }
                if (element == null)
                {
                    MessageBox.Show(rule.Key + " 的元素对象有" + rule.Value.Count + "个");
                    return(true);
                }

                var node = element as ABnfNodeElement;
                if (node == null)
                {
                    MessageBox.Show(rule.Key + "不是ABnfNodeElement类型");
                    return(true);
                }

                ABnfNodeElement value = null;
                foreach (var child in node.GetChilds())
                {
                    if (child.GetNodeType() == "Node" && child is ABnfNodeElement)
                    {
                        value = child as ABnfNodeElement;
                    }
                }
                if (value == null)
                {
                    MessageBox.Show(rule.Key + "不是ABnfNodeElement类型");
                    return(true);
                }

                CollectCompileInfo info = new CollectCompileInfo();
                CollectCompile(value, info, false);

                // 这里开始生成
                string buffer = Properties.Resources.ABnfElementTemplate;

                // 替换协议名字
                buffer = buffer.Replace("@@LANGUAGE@@", language_name);
                buffer = buffer.Replace("@@NAME@@", rule.Key);

                add_new_buffer += "            m_create_map[\"" + rule.Key + "\"] = (factory, file, line, col, offset, type) => { return new " + language_name + rule.Key + "Element(factory, file, line, col, offset, type); };\n";

                string get_child_buffer = "";
                foreach (var id_pair in info.id_map)
                {
                    if (id_pair.Value == 1)
                    {
                        get_child_buffer += Properties.Resources.ABnfGetChildTemplate.Replace("@@LANGUAGE@@", language_name).Replace("@@NAME@@", id_pair.Key);
                    }
                    else if (id_pair.Value > 1)
                    {
                        get_child_buffer += Properties.Resources.ABnfGetChildListTemplate.Replace("@@LANGUAGE@@", language_name).Replace("@@NAME@@", id_pair.Key);
                    }
                }

                if (info.has_key == 1)
                {
                    get_child_buffer += Properties.Resources.ABnfGetChildTemplate.Replace("@@LANGUAGE@@", language_name).Replace("@@NAME@@", "Key");
                }
                else if (info.has_key > 1)
                {
                    get_child_buffer += Properties.Resources.ABnfGetChildListTemplate.Replace("@@LANGUAGE@@", language_name).Replace("@@NAME@@", "Key");
                }

                if (info.has_string == 1)
                {
                    get_child_buffer += Properties.Resources.ABnfGetChildTemplate.Replace("@@LANGUAGE@@", language_name).Replace("@@NAME@@", "String");
                }
                else if (info.has_string > 1)
                {
                    get_child_buffer += Properties.Resources.ABnfGetChildListTemplate.Replace("@@LANGUAGE@@", language_name).Replace("@@NAME@@", "String");
                }

                if (info.has_regex == 1)
                {
                    get_child_buffer += Properties.Resources.ABnfGetChildTemplate.Replace("@@LANGUAGE@@", language_name).Replace("@@NAME@@", "Regex");
                }
                else if (info.has_regex > 1)
                {
                    get_child_buffer += Properties.Resources.ABnfGetChildListTemplate.Replace("@@LANGUAGE@@", language_name).Replace("@@NAME@@", "Regex");
                }

                buffer = buffer.Replace("@@ELEMENT_GET_CHILD@@", get_child_buffer);
                string file_path = path + "\\" + language_name + rule.Key + "Element.cs";
                try
                {
                    File.WriteAllText(file_path, buffer);
                }
                catch (System.Exception)
                {
                    MessageBox.Show(file_path + " 生成失败");
                    return(true);
                }
            }

            {
                // 生成KeyElement
                string buffer    = Properties.Resources.ABnfKeyElementTemplate.Replace("@@LANGUAGE@@", language_name);
                string file_path = path + "\\" + language_name + "KeyElement.cs";
                try
                {
                    File.WriteAllText(file_path, buffer);
                }
                catch (System.Exception)
                {
                    MessageBox.Show(file_path + " 生成失败");
                    return(true);
                }
            }

            {
                // 生成StringElement
                string buffer    = Properties.Resources.ABnfStringElementTemplate.Replace("@@LANGUAGE@@", language_name);
                string file_path = path + "\\" + language_name + "StringElement.cs";
                try
                {
                    File.WriteAllText(file_path, buffer);
                }
                catch (System.Exception)
                {
                    MessageBox.Show(file_path + " 生成失败");
                    return(true);
                }
            }

            {
                // 生成RegexElement
                string buffer    = Properties.Resources.ABnfRegexElementTemplate.Replace("@@LANGUAGE@@", language_name);
                string file_path = path + "\\" + language_name + "RegexElement.cs";
                try
                {
                    File.WriteAllText(file_path, buffer);
                }
                catch (System.Exception)
                {
                    MessageBox.Show(file_path + " 生成失败");
                    return(true);
                }
            }

            {
                // 生成Factory
                string buffer    = Properties.Resources.ABnfFactoryTemplate.Replace("@@LANGUAGE@@", language_name).Replace("@@ELEMENT_ADD_CREATE@@", add_new_buffer);
                string file_path = path + "\\" + language_name + "Factory.cs";
                try
                {
                    File.WriteAllText(file_path, buffer);
                }
                catch (System.Exception)
                {
                    MessageBox.Show(file_path + " 生成失败");
                    return(true);
                }
            }

            MessageBox.Show("生成成功");
            return(true);
        }
예제 #13
0
        // 高亮标签
        public void QueryHighlightWordTag(ABnfElement element, List <ALanguageHighlightWordInfo> info_list)
        {
            // 找到对应的配对
            string value = element.GetElementText();

            if (m_left_pairs.TryGetValue(value, out string right_pair))
            {
                var parent = element.GetParent();
                if (parent == null)
                {
                    return;
                }

                // 找到所在的位置
                var childs = parent.GetChilds();
                int index  = childs.IndexOf(element);
                if (index < 0)
                {
                    return;
                }

                // 往后找到对应的匹配
                for (int i = index + 1; i < childs.Count; ++i)
                {
                    if (childs[i].GetElementText() == right_pair)
                    {
                        var info = new ALanguageHighlightWordInfo();
                        info.start = element.GetStart();
                        info.end   = element.GetEnd();
                        info_list.Add(info);

                        info       = new ALanguageHighlightWordInfo();
                        info.start = childs[i].GetStart();
                        info.end   = childs[i].GetEnd();
                        info_list.Add(info);

                        break;
                    }
                }
                return;
            }

            // 找到对应的配对
            if (m_right_pairs.TryGetValue(value, out string left_pair))
            {
                var parent = element.GetParent();
                if (parent == null)
                {
                    return;
                }

                // 找到所在的位置
                var childs = parent.GetChilds();
                int index  = childs.IndexOf(element);
                if (index < 0)
                {
                    return;
                }

                // 往前找到对应的匹配
                for (int i = index - 1; i >= 0; --i)
                {
                    if (childs[i].GetElementText() == left_pair)
                    {
                        var info = new ALanguageHighlightWordInfo();
                        info.start = element.GetStart();
                        info.end   = element.GetEnd();
                        info_list.Add(info);

                        info       = new ALanguageHighlightWordInfo();
                        info.start = childs[i].GetStart();
                        info.end   = childs[i].GetEnd();
                        info_list.Add(info);

                        break;
                    }
                }
                return;
            }

            ABnfNodeElement node = element as ABnfNodeElement;

            if (node == null)
            {
                node = element.GetParent();
            }
            if (node == null)
            {
                return;
            }

            // 找到高亮配对
            node.GetReference().QueryHighlightWordTag(info_list);
        }
예제 #14
0
        // 获取信息
        public void QueryQuickInfo(int offset)
        {
            // 获取元素
            var element = GetException(offset);

            if (element == null)
            {
                return;
            }

            if (element is ABnfErrorElement)
            {
                return;
            }

            // 获取类型
            ABnfNodeElement node = element as ABnfNodeElement;

            if (node == null)
            {
                node = element.GetParent();
            }
            if (node == null)
            {
                return;
            }
            element = node;

            var info = node.GetReference().QueryQuickInfo();

            if (info == null)
            {
                return;
            }

            int start  = element.GetStart();
            int length = element.GetLength();

            Application.Current.Dispatcher.Invoke(() =>
            {
                if (m_view.TextBuffer.Properties.TryGetProperty(nameof(ALanguageQuickInfoSource), out ALanguageQuickInfoSource source))
                {
                    source.RefreshQuickInfo(start, length, info);
                    if (m_view.Properties.TryGetProperty(nameof(ALanguageController), out ALanguageController controller))
                    {
                        controller.StartQuickInfo(start);
                    }
                }
                else
                {
                    if (m_view.Properties.TryGetProperty(nameof(ALanguageController), out ALanguageController controller))
                    {
                        controller.StartQuickInfo(start);
                    }
                    if (m_view.TextBuffer.Properties.TryGetProperty(nameof(ALanguageQuickInfoSource), out source))
                    {
                        source.RefreshQuickInfo(start, length, info);
                    }
                }
            });
        }
예제 #15
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);
        }
예제 #16
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);
        }
예제 #17
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);
        }
예제 #18
0
        private bool CheckAutoPair(int offset, char left_pair, string right_pair)
        {
            if (m_indent_root == null)
            {
                var file = new UIABnfFile(m_full_path, m_abnf_ui, m_view.TextBuffer.CurrentSnapshot.GetText());
                m_indent_root = m_abnf_ui.Analysis(file);
            }

            if (m_indent_root == null)
            {
                return(false);
            }

            // 获取元素
            var element = m_indent_root.GetException(offset - 1);

            if (element == null)
            {
                return(false);
            }

            // 如果是错误元素,那么就以目标元素来判定
            if (element is ABnfErrorElement)
            {
                var error_element = element as ABnfErrorElement;
                if (error_element.GetTargetElement() is ABnfRegexElement)
                {
                    return((error_element.GetTargetElement() as ABnfRegexElement).IsMatch(left_pair + right_pair));
                }
                return(false);
            }

            // 如果是正则表达式,那么就直接匹配
            if (element is ABnfRegexElement)
            {
                return((element as ABnfRegexElement).IsMatch(left_pair + right_pair));
            }

            // 获取类型
            ABnfNodeElement node = element as ABnfNodeElement;

            if (node == null)
            {
                node = element.GetParent();
            }
            if (node == null)
            {
                return(false);
            }

            // 查找规则
            var rule = m_abnf.GetRule(node.GetNodeType());

            foreach (var node_list in rule.node.node_list)
            {
                // 如果还有一个子规则,那么就跳过
                if (node_list.Count <= 1)
                {
                    continue;
                }

                // 如果找到规则并且和left_pair一致,那么就找到left_pair对应的规则
                int index = -1;
                for (int i = 0; i < node_list.Count; ++i)
                {
                    var node_token = node_list[i];
                    if (node_token.value == null)
                    {
                        continue;
                    }

                    if (node_token.value.type == ABnfRuleTokenType.TT_STRING)
                    {
                        if (node_token.value.value.Length == 1 &&
                            node_token.value.value[0] == left_pair)
                        {
                            index = i;
                            break;
                        }
                    }
                }
                // 如果没有找到就跳过当前规则组
                if (index == -1)
                {
                    continue;
                }
                // 从后面往前找,找到与right_pair配对的子规则,如果有,那么就返回true
                for (int i = node_list.Count - 1; i >= index + 1; --i)
                {
                    var node_token = node_list[i];
                    if (node_token.value == null)
                    {
                        continue;
                    }

                    if (node_token.value.type == ABnfRuleTokenType.TT_STRING)
                    {
                        if (node_token.value.value == right_pair)
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
예제 #19
0
 // 设置父节点
 internal void SetParent(ABnfNodeElement parent)
 {
     m_parent = parent;
 }