2

假设我有一个规则:

myCoolRule:
     Word
     | 'myCoolToken' Word otherRule

我提供作为输入myCoolToken something else now,它试图将其解析为贪婪地将 myCoolToken 匹配为一个单词,然后点击something并说 uhhh 我期望 EOF,如果我安排规则以便它首先尝试匹配myCoolToken,那么对于该输入来说一切都很好并且完美解析。

我想知道它是否有可能继续尝试该语句中的所有规则以查看是否有效。所以它匹配 Word 失败,返回然后尝试下一条规则。

这是导致问题的实际语法规则:

columnName = Word;
typeName = Word;

//accepts CAST and cast
cast =  { MATCHES_IGNORE_CASE(LS(1), @"CAST") }? Word ;

checkConstraint = 'CHECK' '('! expr ')'!;

expr        = requiredExp optionalExp*;

requiredExp =  (columnName
               | cast '(' expr as typeName ')'
               ... more but not important
optionalExp ...not important

输入CHECK( CAST( abcd as defy) )导致它失败,即使它是有效的

是否有构造或其他方式使其在放弃之前验证所有规则。

4

1 回答 1

1

PEGKit的创建者在这里。

如果我理解你的问题,不,这是不可能的。但这是 PEGKit 的一个特性,而不是一个错误。

您的问题与“确定性”与“不确定性”有关。PEGKit 是一个“确定性”工具包(被广泛认为是解析编程语言的理想特性)。

在这种情况下,您似乎正在寻找一种更“不确定”的行为,但我认为您不应该这样做:)。

PEGKit 允许您通过替代选项的列出顺序来指定替代选项的优先级。所以:

foo = highPriority
    | lowerPriority
    | lowestPriority
    ;

如果highPriority选项与当前输入匹配,则lowerPriorityandlowestPriority选项将没有机会尝试匹配,即使它们以某种方式是“更好”的匹配(即它们匹配比 更多的标记highPriority)。

同样,这与“确定性”有关(highPriority保证被优先考虑),并且在解析编程语言时被广泛认为是一个理想的特性。

因此,如果您希望cast()表达式的优先级高于columnName,只需将cast()表达式列为选项之前columnName选项即可。

requiredExp =  (cast '(' expr as typeName ')'
               | columnName
               ... more but not important


好的,这样就可以处理语法细节。但是,如果您有更高级别的语义约束,这可能会影响关于哪个替代方案应具有最高优先级的解析时决策,您应该使用Semantic Predicate,例如:

foo = { shouldChooseOpt1() }? opt1
    | { shouldChooseOpt2() }? opt2
    | defaultOpt
    ;

有关语义谓词的更多详细信息,请参见此处

于 2014-04-26T12:50:17.457 回答