// 函数调用参数提示 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); } } }); }
// 行注释匹配 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); } } }
// 拾取高亮 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); } }); }
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); }
// 跳转 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); } }); }
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); } } }
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); }
// 规则节点 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); }
// 分析规则语句 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); }
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); }
// 字符串匹配 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); }
// 生成文件 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); }
// 高亮标签 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); }
// 获取信息 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); } } }); }
// 分析节点 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); }
// 关键字匹配 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); }
// 正则表达式匹配 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); }
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); }
// 设置父节点 internal void SetParent(ABnfNodeElement parent) { m_parent = parent; }