如何将此语法更改为确定性
e --> [].
e --> "*".
e --> s_e.
e --> e, s_e.
s_e --> ("a",e);("b",e).
我只是不知道放在哪里以避免回溯。
答案 0 :(得分:2)
您可以按如下方式重写最后一条规则:
s_e --> "a", e.
s_e --> "b", e.
现在放置以下剪辑可能是有意义的:
s_e --> "a", !, e.
s_e --> "b", !, e.
您也可以将剪裁放在原始的紧凑型中 形式与(;)/ 2,但我发现上面更透明。 如果未多次调用s_e,则上述条件有效 具有相同输入列表的时间。
但你的语法有一个缺陷,e是递归的, 和s_e将被多次调用相同 输入列表。意味着你的语法将是例如 否定句子的循环,即它将无法 拒绝他们,你的语法将循环 重做正面句子,即输入时 已被接受。
所以你需要另外消除左边 递归自正常Prolog深度拳头搜索 不能处理它。最简单的是替换它 使用新的非终端进行正确的递归。就是你 可以按如下方式为e编写作品:
e --> s_e, rest_e.
e --> "*", rest_e.
e --> [].
rest_e --> s_e, rest_e.
rest_e --> "*", rest_e.
rest_e --> [].
我们也可以进行削减:
e --> s_e, !, rest_e.
e --> "*", !, rest_e.
e --> [].
rest_e --> s_e, !, rest_e.
rest_e --> "*", !, rest_e.
rest_e --> [].
上面的语法也略有修改 多个空电子制作没有的感觉 通过s_e进入e本身。还有更多 贪婪,因为副作品总是充分的 解析。例如,句子:
aaa
仅解析为:
a(a(a))
而不是:
a(a)a
或者:
aa(a)
或者:
aaa
但是否则它应该接受与DCG相同的句子 将自下而上执行,但不会 左递归的问题。
最好的问候