PegKit:语法语法,以不同的方式处理相同的工作

时间:2015-07-01 03:29:29

标签: ios syntax pegkit

我正在研究一些使用PegKit的代码,而且我遇到了一些我不知道如何解决的问题。我的语法看起来像这样(简化):

expr = runtimeExpr | objectExpr;
runtimeExpr = is? runtimeObject;
objectExpr = runtimeObject keyPath;
runtimeObject = '[' string ']';
is = 'is';
keyPath = string;

我正在寻找以下结果:

[abc] -> runtime expr.
is [abc] -> runtime expr.
[abc].def -> object expr.

然而,生成的解析器代码如下所示:

if ([self predicts:STLOGEXPRESSIONPARSER_TOKEN_KIND_IS, 0]) {
    [self runtimeExpr_]; 
} else if ([self predicts:STLOGEXPRESSIONPARSER_TOKEN_KIND_OPEN_BRACKET, 0]) {
    [self objectExpr_]; 
}

有效的说,为了解析运行时expr,它必须以'is'开头。这意味着[abc]将作为对象expr传递。

所以我需要帮助的是理解如何在语法语法中表达这个逻辑:

  1. 如果字符串以'is'开头,后跟runtimeObject,或者只是runtimeObject,则将其作为runtimeExpr处理。

  2. 否则将其作为objectExpr。

  3. 处理

1 个答案:

答案 0 :(得分:1)

PEGKit的创作者。

我认为这里的问题是领先的可选is?。任何以这样的可选前缀开头的规则,然后匹配与其他规则相似或相同的内容(在这种情况下为runtimeObject)可能会导致问题。

但解决方案很简单。只需重新排序一下。 PEGKit 确定性,这意味着它将按照您在语法中指定的顺序尝试 OR 替代方案。因此,在这种情况下,只需在objectExpr规则中放置更长备用规则(runtimeExpr优先expr之前)。< / p>

试试这个,我相信一切都会成功:

expr = objectExpr | runtimeExpr;
objectExpr = runtimeObject keyPath;
runtimeExpr = is runtimeObject | runtimeObject;
runtimeObject = '[' string ']';
is = 'is';
keyPath = string;

请注意我对exprruntimeExpr规则所做的更改。我怀疑只有expr的更改才能解决这个问题,但对runtimeExpr的更改是无害的。实验应该告诉您实际上是否需要runtimeExpr更改。