4

用户输入的格式为 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.

无法修改输入。任何建议都值得赞赏。谢谢!

4

1 回答 1

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加载、执行和 ; 并重新加载它。

为了使操作符声明生效,要么直接在顶层执行它(这是一个快速的hack);或将其作为指令写入文件或模块。

然后>-like 运算符,我将使用:>它的位置,需要像 the:和下面的优先级那样是右结合的:。您声明xfx这意味着没有关联性。

?- op(500,xfy,:>).
true.

?- write_canonical(a:b:>c:>d).
:(a,:>(b,:>(c,d)))
true.
于 2013-01-01T21:48:32.087 回答