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); }
// 解析规则节点 ABnfRuleNodeInfo CalcABnfNode(List <ABnfRuleTokenInfo> token_list, ref int offset) { ABnfRuleNodeInfo node = new ABnfRuleNodeInfo(); while (offset < token_list.Count) { ABnfRuleTokenInfo token = token_list[offset]; // 如果是注释,那么就跳过 if (token.type == ABnfRuleTokenType.TT_LINE_COMMENT || token.type == ABnfRuleTokenType.TT_BLOCK_COMMENT) { ++offset; continue; } // 检查ID if (token.type == ABnfRuleTokenType.TT_ID) { // 正则表达式匹配 if (!Regex.IsMatch(token.value, "^[_a-zA-Z][_a-zA-Z0-9]*$")) { throw new System.Exception("行:" + token.line + "列:" + token.col + "ID 必须以小写字母、大写字母、数字、下划线,并且不能以数字开头,但是得到是:" + token.value); } if (node.node_list.Count == 0) { node.node_list.Add(new List <ABnfRuleNodeInfo>()); } node.node_list[node.node_list.Count - 1].Add(new ABnfRuleNodeInfo(token)); ++offset; continue; } // 检查字符串 if (token.type == ABnfRuleTokenType.TT_STRING || token.type == ABnfRuleTokenType.TT_KEY || token.type == ABnfRuleTokenType.TT_REGEX) { if (node.node_list.Count == 0) { node.node_list.Add(new List <ABnfRuleNodeInfo>()); } node.node_list[node.node_list.Count - 1].Add(new ABnfRuleNodeInfo(token)); ++offset; continue; } // 最后检查符号 if (token.type == ABnfRuleTokenType.TT_SYMBOL) { if (token.value == "(") { ++offset; if (node.node_list.Count == 0) { node.node_list.Add(new List <ABnfRuleNodeInfo>()); } node.node_list[node.node_list.Count - 1].Add(CalcABnfNode(token_list, ref offset)); if (offset >= token_list.Count || token_list[offset].value != ")") { throw new System.Exception("行:" + token.line + "列:" + token.col + "期望是),但得到的是:" + token.value); } ++offset; continue; } else if (token.value == "*") { if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0) { throw new System.Exception("行:" + token.line + "列:" + token.col + "符号*前面没有定义内容"); } var node_list = node.node_list[node.node_list.Count - 1]; if (node_list[node_list.Count - 1].repeat != ABnfRuleNodeRepeatType.NRT_NONE) { throw new System.Exception("行:" + token.line + "列:" + token.col + "符号*前面已经定义了重复规则"); } node_list[node_list.Count - 1].repeat = ABnfRuleNodeRepeatType.NRT_NOT_OR_MORE; ++offset; continue; } else if (token.value == "+") { if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0) { throw new System.Exception("行:" + token.line + "列:" + token.col + "符号+前面没有定义内容"); } var node_list = node.node_list[node.node_list.Count - 1]; if (node_list[node_list.Count - 1].repeat != ABnfRuleNodeRepeatType.NRT_NONE) { throw new System.Exception("行:" + token.line + "列:" + token.col + "符号+前面已经定义了重复规则"); } node_list[node_list.Count - 1].repeat = ABnfRuleNodeRepeatType.NRT_AT_LEAST_ONE; ++offset; continue; } else if (token.value == "?") { if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0) { throw new System.Exception("行:" + token.line + "列:" + token.col + "符号?前面没有定义内容"); } var node_list = node.node_list[node.node_list.Count - 1]; if (node_list[node_list.Count - 1].repeat != ABnfRuleNodeRepeatType.NRT_NONE) { throw new System.Exception("行:" + token.line + "列:" + token.col + "符号?前面已经定义了重复规则"); } node_list[node_list.Count - 1].repeat = ABnfRuleNodeRepeatType.NRT_ONE_OR_NOT; ++offset; continue; } else if (token.value == "@") { if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0) { throw new System.Exception("行:" + token.line + "列:" + token.col + "符号@前面没有定义内容"); } var node_list = node.node_list[node.node_list.Count - 1]; if (node_list[node_list.Count - 1].pin != ABnfRuleNodePinType.NPT_NONE) { throw new System.Exception("行:" + token.line + "列:" + token.col + "符号@前面已经定义了pin规则"); } node_list[node_list.Count - 1].pin = ABnfRuleNodePinType.NPT_TRUE; ++offset; continue; } else if (token.value == "#") { if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0) { throw new System.Exception("行:" + token.line + "列:" + token.col + "符号#前面没有定义内容"); } var node_list = node.node_list[node.node_list.Count - 1]; if (node_list[node_list.Count - 1].not_key != ABnfRuleNodeNotKeyType.NNKT_NONE) { throw new System.Exception("行:" + token.line + "列:" + token.col + "符号#前面已经定义了非key规则"); } node_list[node_list.Count - 1].not_key = ABnfRuleNodeNotKeyType.NNKT_TRUE; ++offset; continue; } else if (token.value == "|") { if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0) { throw new System.Exception("行:" + token.line + "列:" + token.col + "符号|前面没有定义内容"); } if (offset + 1 >= token_list.Count && token_list[offset + 1].type == ABnfRuleTokenType.TT_SYMBOL && token_list[offset + 1].value == ";") { throw new System.Exception("行:" + token.line + "列:" + token.col + "符号|后面没有定义内容"); } node.node_list.Add(new List <ABnfRuleNodeInfo>()); ++offset; continue; } else if (token.value == ";" || token.value == ")") { break; } else { throw new System.Exception("行:" + token.line + "列:" + token.col + "当前不能处理:" + token.value); } } throw new System.Exception("行:" + token.line + "列:" + token.col + "未知的token类型:" + token.value); } return(node); }
// 字符串匹配 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); }
// 关键字匹配 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 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 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); }
// 正则表达式匹配 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 ABnfRuleNodeInfo CalcABnfNode(List <ABnfRuleTokenInfo> token_list, ref int offset) { ABnfRuleNodeInfo node = new ABnfRuleNodeInfo(); while (offset < token_list.Count) { ABnfRuleTokenInfo token = token_list[offset]; // 如果是注释,那么就跳过 if (token.type == ABnfRuleTokenType.TT_LINE_COMMENT || token.type == ABnfRuleTokenType.TT_BLOCK_COMMENT) { ++offset; continue; } // 检查ID if (token.type == ABnfRuleTokenType.TT_ID) { // 正则表达式匹配 if (!Regex.IsMatch(token.value, "^[_a-zA-Z][_a-zA-Z0-9]*$")) { throw new System.Exception("Line: " + token.line + ", Col: " + token.col + "ID must start with lowercase letters, uppercase letters, numbers, and underscores, and cannot start with a number, but the result is: " + token.value); } if (node.node_list.Count == 0) { node.node_list.Add(new List <ABnfRuleNodeInfo>()); } node.node_list[node.node_list.Count - 1].Add(new ABnfRuleNodeInfo(token)); ++offset; continue; } // 检查字符串 if (token.type == ABnfRuleTokenType.TT_STRING || token.type == ABnfRuleTokenType.TT_KEY || token.type == ABnfRuleTokenType.TT_REGEX) { if (node.node_list.Count == 0) { node.node_list.Add(new List <ABnfRuleNodeInfo>()); } node.node_list[node.node_list.Count - 1].Add(new ABnfRuleNodeInfo(token)); ++offset; continue; } // 最后检查Left hand of if (token.type == ABnfRuleTokenType.TT_SYMBOL) { if (token.value == "(") { ++offset; if (node.node_list.Count == 0) { node.node_list.Add(new List <ABnfRuleNodeInfo>()); } node.node_list[node.node_list.Count - 1].Add(CalcABnfNode(token_list, ref offset)); if (offset >= token_list.Count || token_list[offset].value != ")") { throw new System.Exception("Line: " + token.line + ", Col: " + token.col + "The expectation is), but what I get is: " + token.value); } ++offset; continue; } else if (token.value == "*") { if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0) { throw new System.Exception("Line: " + token.line + ", Col: " + token.col + "No content defined in front of the symbol * "); } var node_list = node.node_list[node.node_list.Count - 1]; if (node_list[node_list.Count - 1].repeat != ABnfRuleNodeRepeatType.NRT_NONE) { throw new System.Exception("Line: " + token.line + ", Col: " + token.col + "The symbol * has previously defined the repetition rule "); } node_list[node_list.Count - 1].repeat = ABnfRuleNodeRepeatType.NRT_NOT_OR_MORE; ++offset; continue; } else if (token.value == "+") { if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0) { throw new System.Exception("Line: " + token.line + ", Col: " + token.col + "Symbol + no content defined in front "); } var node_list = node.node_list[node.node_list.Count - 1]; if (node_list[node_list.Count - 1].repeat != ABnfRuleNodeRepeatType.NRT_NONE) { throw new System.Exception("Line: " + token.line + ", Col: " + token.col + "Symbol + The repetition rule has been defined before "); } node_list[node_list.Count - 1].repeat = ABnfRuleNodeRepeatType.NRT_AT_LEAST_ONE; ++offset; continue; } else if (token.value == "?") { if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0) { throw new System.Exception("Line: " + token.line + ", Col: " + token.col + "Symbol ? No content defined in front "); } var node_list = node.node_list[node.node_list.Count - 1]; if (node_list[node_list.Count - 1].repeat != ABnfRuleNodeRepeatType.NRT_NONE) { throw new System.Exception("Line: " + token.line + ", Col: " + token.col + "Symbol ? has been defined previously"); } node_list[node_list.Count - 1].repeat = ABnfRuleNodeRepeatType.NRT_ONE_OR_NOT; ++offset; continue; } else if (token.value == "@") { if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0) { throw new System.Exception("Line: " + token.line + ", Col: " + token.col + "Left hand of @ is missing"); } var node_list = node.node_list[node.node_list.Count - 1]; if (node_list[node_list.Count - 1].pin != ABnfRuleNodePinType.NPT_NONE) { throw new System.Exception("Line: " + token.line + ", Col: " + token.col + "Symbol @ is defined after the pin rule"); } node_list[node_list.Count - 1].pin = ABnfRuleNodePinType.NPT_TRUE; ++offset; continue; } else if (token.value == "#") { if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0) { throw new System.Exception("Line: " + token.line + ", Col: " + token.col + "Left hand of # is missing"); } var node_list = node.node_list[node.node_list.Count - 1]; if (node_list[node_list.Count - 1].not_key != ABnfRuleNodeNotKeyType.NNKT_NONE) { throw new System.Exception("Line: " + token.line + ", Col: " + token.col + "Left hand of # has been defined previously"); } node_list[node_list.Count - 1].not_key = ABnfRuleNodeNotKeyType.NNKT_TRUE; ++offset; continue; } else if (token.value == "|") { if (node.node_list.Count == 0 || node.node_list[node.node_list.Count - 1].Count == 0) { throw new System.Exception("Line: " + token.line + ", Col: " + token.col + "Left hand of | is missing"); } if (offset + 1 >= token_list.Count && token_list[offset + 1].type == ABnfRuleTokenType.TT_SYMBOL && token_list[offset + 1].value == ";") { throw new System.Exception("Line: " + token.line + ", Col: " + token.col + "Right hand of | is missing"); } node.node_list.Add(new List <ABnfRuleNodeInfo>()); ++offset; continue; } else if (token.value == ";" || token.value == ")") { break; } else { throw new System.Exception("Line: " + token.line + ", Col: " + token.col + "Unsupported:" + token.value); } } throw new System.Exception("Line: " + token.line + ", Col: " + token.col + "Unknown token type:" + token.value); } return(node); }