假设我有一条规则:
myCoolRule:
Word
| 'myCoolToken' Word otherRule
我提供输入myCoolToken something else now
它试图解析它贪婪地匹配myCoolToken作为一个单词然后点击something
并说uhhh我期望EOF,如果我安排规则所以它试图匹配{ {1}}首先一切都很好并且完全解析,输入。
我想知道它是否有可能继续尝试该声明中的所有规则以查看是否有效。因此它匹配Word失败,返回然后尝试下一个规则。
以下是导致问题的实际语法规则:
myCoolToken
输入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
导致它失败,即使有效
是否存在构造或以其他方式使其在放弃之前验证所有规则。
答案 0 :(得分:1)
PEGKit的创作者。
如果我理解你的问题,不,这是不可能的。但这是PEGKit的一个特征,而不是一个bug。
您的问题与"确定性"有关。 vs" nondeterminacy"。 PEGKit是一种确定性的" toolkit(被广泛认为是解析编程语言的理想特性)。
看来你正在寻找一个更加不确定的"在这种情况下的行为,但我认为你应该是:)。
PEGKit允许您通过列出备用选项的顺序指定备用选项的优先级。所以:
foo = highPriority
| lowerPriority
| lowestPriority
;
如果highPriority
选项与当前输入匹配,则lowerPriority
和lowestPriority
选项不将有机会尝试匹配,即使它们是某种程度上"更好"匹配(即匹配的代币数多于highPriority
)。
同样,这与"确定性"有关。 (highPriority
保证优先考虑)并且在解析编程语言时被广泛认为是理想的特性。
因此,如果您希望cast()
表达式的优先级高于columnName
,则只需将cast()
表达式列为选项,然后再 {{1}选项。
columnName
<小时/> 好的,这样可以处理 语法 的详细信息。但是,如果您有更高级别的 语义 约束,这些约束会影响解析时决定哪个备选应具有最高优先级,则应使用语义谓词,如:
requiredExp = (cast '(' expr as typeName ')'
| columnName
... more but not important