PegKit:以不同方式处理相同工作的语法语法
PegKit: Grammar syntax which handles same work in different ways
我正在编写一些使用 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_];
}
有效表示为了解析运行时表达式,它必须以 'is' 开头。这意味着 [abc]
将作为对象 expr 传递。
所以我需要帮助的是理解如何在语法语法中表达这个逻辑:
如果字符串以'is'开头,后跟一个runtimeObject,或者只是一个runtimeObject,则将其作为runtimeExpr处理。
否则作为objectExpr处理
这里是 PEGKit 的创建者。
我认为这里的问题是领先的可选 is?
。任何以这样的可选前缀开头,然后匹配与另一条规则相似或相同的规则(在本例中为 runtimeObject
)都可能导致问题。
但解决方法很简单。稍微重新排序一下。 PEGKit 是 deterministic 这意味着它将按照您在语法中指定的顺序尝试 OR 替代方案。因此,在这种情况下,只需放置 longer 替代规则 (objectExpr
) first(在 runtimeExpr
之前 expr
规则)。
试试这个,我相信一切都会成功的:
expr = objectExpr | runtimeExpr;
objectExpr = runtimeObject keyPath;
runtimeExpr = is runtimeObject | runtimeObject;
runtimeObject = '[' string ']';
is = 'is';
keyPath = string;
请注意我对 expr
和 runtimeExpr
规则所做的更改。我怀疑只有更改 expr
才能解决此问题,但更改 runtimeExpr
是无害的。实验应该会告诉您 runtimeExpr
更改是否真的有必要。
我正在编写一些使用 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_];
}
有效表示为了解析运行时表达式,它必须以 'is' 开头。这意味着 [abc]
将作为对象 expr 传递。
所以我需要帮助的是理解如何在语法语法中表达这个逻辑:
如果字符串以'is'开头,后跟一个runtimeObject,或者只是一个runtimeObject,则将其作为runtimeExpr处理。
否则作为objectExpr处理
这里是 PEGKit 的创建者。
我认为这里的问题是领先的可选 is?
。任何以这样的可选前缀开头,然后匹配与另一条规则相似或相同的规则(在本例中为 runtimeObject
)都可能导致问题。
但解决方法很简单。稍微重新排序一下。 PEGKit 是 deterministic 这意味着它将按照您在语法中指定的顺序尝试 OR 替代方案。因此,在这种情况下,只需放置 longer 替代规则 (objectExpr
) first(在 runtimeExpr
之前 expr
规则)。
试试这个,我相信一切都会成功的:
expr = objectExpr | runtimeExpr;
objectExpr = runtimeObject keyPath;
runtimeExpr = is runtimeObject | runtimeObject;
runtimeObject = '[' string ']';
is = 'is';
keyPath = string;
请注意我对 expr
和 runtimeExpr
规则所做的更改。我怀疑只有更改 expr
才能解决此问题,但更改 runtimeExpr
是无害的。实验应该会告诉您 runtimeExpr
更改是否真的有必要。