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ロードし、実行し、そして; そしてそれをリロードしました。

演算子宣言を有効にするには、トップレベルで直接実行します(これは簡単なハックです)。または、ディレクティブとしてファイルまたはモジュールに書き込みます。

次に、>-like演算子は、:>その場所で使用します。のように右結合である必要が:あり、以下の優先順位が必要:です。あなたはxfx、これは結合性がないことを意味すると宣言しました。

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

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