EBNF解析器发出识别零个或多个子句错误的问题

时间:2018-06-19 16:16:03

标签: parsing ebnf

我已经下载并修改了第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,名称:'”附近的语法错误

我知道必须先遇到此问题,而我的问题是如何解决?

0 个答案:

没有答案