我已经下载并修改了第3方解析器以识别类似JSON的语言。原始解析器位于https://github.com/b3b00/csly。它在大多数情况下都有效,但是我必须进行一些修改。这些修改与问题无关。
我遇到的问题是解析零个或多个子句。当遇到问题时,它并没有报告正确的错误消息,我不得不花太多时间进行调试以弄清真正的问题是什么。下面,我写了一些伪代码来说明它如何解析零个或多个子句。
ParseResult ParseZeroOrMoreClause(
IList<Token> tokens,
Clause clause,
int currentPosition) {
var children = new List<Node>();
var ok = true;
while (ok) {
// attempt to parse the clause
var result = Parse(tokens, clause, currentPosition);
if (!result.IsError) {
// add the parsed results node to the list of children
children.Add(result.Node);
// Move the current position to the end of the parsed result
currentPosition = result.EndingPosition;
} else {
// We were not able to parse another zeroOrMoreClause
// we can stop and currentPosition will be the end position
// of the last successfully parsed clause, if any
ok = false;
}
}
// there is never an error parsing in this function
return new ParseResult {
IsError = false,
EndingPosition = currentPosition,
Children = children
};
}
问题在于,由于没有更多的子句并且读取了最后一个子句,或者因为存在需要向用户报告的语法错误,因此很难确定是否要停止。
以下是JSON列表的生产规则:
// empty list
list => listStart listEnd
// list with elements
list => listStart listElements listEnd
// elements within a list
listElements => value additionalListElement*
// additional list elements
additionalListElement => Seperator value
有效的示例JSON列表:
[
{ Id: 1, Name: "John" },
{ Id: 2, Name: "Bobby" },
{ Id: 3, Name: George }
]
列表的第一个规则是EmptyList,因此解析器首先尝试识别空列表。解析器将识别开始列表符号'[',然后将期望结束列表符号']',但找不到它,因此该规则不起作用。
下一条规则是带有元素的列表。它将识别列表开始符号。然后,它将尝试识别listElements,它是一个值,后跟零个或多个AdditionalListItem规则。它将对象'{Id:1,Name:“ John”}'识别为值。然后它将尝试识别零个或多个定义为分隔符和值的AdditionalListItem规则。它将识别分隔符和下一个对象'{ID:2,名称:“ Bobby”}'作为值。它将尝试识别紧随该对象之后的另一个anotherListItem,但由于存在语法错误而将失败。文本“ George”没有用双引号引起来。这将导致函数ParseZeroOrMore停止并将当前位置设置为恰好在失败的AdditionalListElement之前,该位置恰好在最后一个分隔符之前。解析继续进行,带有元素的列表规则指出,列表末尾mbol必须是下一个符号。我得到的错误是“预期的列表末尾']',但在第...列...行中找到了分隔符','”。我期望的错误是“'{Id:3,名称:'”附近的语法错误
我知道必须先遇到此问题,而我的问题是如何解决?