我想解析 - 跳过Forth-style如果来自输入,Forth-style意味着每个如果开始if和结束then,假设所有输入都是正确的不匹配处理不是必需的.
问题是每个部分都if可以递归地包含任意数量的其他部分if.
这是我测试用例的最佳解决方案:
Red []
skip-nested-ifs: [skip to ['if | 'then] skip-nested-ifs-helper]
skip-nested-ifs-helper: ['then | skip-nested-ifs skip-nested-ifs-helper ]
rules: skip-nested-ifs
test-cases: [
[if a then]
[if a else b then]
[if a if b then then]
[if a if b then 5 then]
[if a if b then 5 if c then then]
[if a else if b then then]
[if a else if b then 5 then]
[if a else if b then if c then then]
[if a if b if c then if d then then then]
]
forall test-cases [
prin [mold test-cases/1 ""]
print either parse test-cases/1 rules [ "OK" ] [ "FAIL" ]
]
Run Code Online (Sandbox Code Playgroud)
输出是:
[if a then] OK
[if a else b then] OK
[if a if b then then] OK
[if a if b then 5 then] FAIL
[if a if b then 5 if c then then] FAIL
[if a else if b then then] OK
[if a else if b then 5 then] FAIL
[if a else if b then if c then then] OK
[if a if b if c then if d then then then] OK
Run Code Online (Sandbox Code Playgroud)
因此,其中三个失败,因为它们5在一个then和另一个之间包含某些东西(在这种情况下).
可能修复非常简单明了,但我现在还没看到.如果可能的话,你能帮我解决上面的规则吗?或者显示一个通过所有测试的不同的规则?
我不确定您的规则是否可修复,因为它严重依赖于递归,但无法提供测试#5所需的迭代支持.我无法修复它,因为skip用于消耗终端和非终端令牌(包括if),所以它让我很难遵循.
我想出了一个不同的解决方案.它更长,但通过所有测试(使用红色):
rules: [
'if skip
opt ['else [some rules | skip]]
opt some rules
'then
opt [some rules | ahead 'then | skip]
]
Run Code Online (Sandbox Code Playgroud)
笔记:
some迭代使用子表达式的用法.ahead 'then防护规则,是否有防止skip从消耗额外的then这将是一个亲本表达的部分(在递归调用的情况下).skip传递下面的终端值,then或者else虽然从您的描述中不清楚是否可以有多个值.无论如何,如果需要,可以很容易地扩展以匹配更复杂的模式.如果你想使用这样的规则来跳过输入,你可以像这样调用它:
skip-ifs: [to 'if rules]
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.