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 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 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); }