用户输入以a:b> c> d> e ...等格式给出。我想将输入解析为:(a,>(b,>(c,>(d,e)))这是可能的,是否有任何建议去做?我用这个测试
prepare:-
op(750,xfx,user:(:)), % change the default priority of : and >
op(700,xfx,user:(>)),
display(a: b > c),%this one worked fine and
%the display value is :(a,>(b,c))
display(a: b > c > d ). % I cannot have this works,
%the error ERROR:
%Syntax error:
%Operator priority clash is thrown.
无法修改输入。任何建议都表示赞赏。谢谢!
答案 0 :(得分:4)
也许首先是:(:)/2
和(>)/2
都是标准中定义的中缀运算符,如下所示:
:- op(600, xfy, :). % ISO/IEC 13211-2 5.2.1, table 1
:- op(700, xfx, >). % ISO/IEC 13211-1 6.3.4.4, table 7
改变他们的优先级意味着你改变他们的共同意义。这通常不是一个好主意。想一想:就像你(能够)改变Java,C#,C ++,Perl或PHP中运算符的优先级一样。他们都不敢改变他们从C继承的优先权。
但是,严格来说,你可以做到这一点。
为了尽量减少此类更改的不利影响,请尝试将声明保留在您自己的模块中。而且,在没有模块本地操作符的系统中,请确保您将安全地恢复到原始声明。
你写了user:(>)
,它影响了特殊的用户模块。相反,编写自己的模块。
......或者可能会重新考虑要更改的操作员。
条款一下子读到下一个时期。因此,如果您有一个像您所示的规则,则只有在执行prepare
时,运算符声明才会生效。因此,它对目标display/1
的论点没有影响。你可能已经prepare
加载,执行了;并重新加载它。
要使操作员声明有效,请直接在顶层执行(即快速入侵);或将其作为指令写入文件或模块。
然后>
- 类似的运算符,我会使用:>
它的位置,需要像:
那样是右关联的,并且优先级低于:
。您声明了xfx
,这意味着没有关联性。
?- op(500,xfy,:>).
true.
?- write_canonical(a:b:>c:>d).
:(a,:>(b,:>(c,d)))
true.