DCG ベースのソリューション
既存のソリューションにDCG ベースのソリューションを追加したいと考えています。
DCG の利点
このタスクに DCG を使用することには、いくつかの大きな利点があります。
- 別のファイルを変更することなく、パーサーをインタラクティブに簡単にテストできます。
- 十分に一般的な DCG を使用して、テスト データの解析と生成を行うことができます。
- このメソッドを知っていると、CSV のような所定の形式に適合しない、より複雑な解析タスクに役立つ場合があります。
予選
次のコードは、次の設定を前提としています。
:- set_prolog_flag(double_quotes, chars)。
DCG の操作が読みやすくなるため、この設定をお勧めします。
建築用ブロック:token//1
まず、トークンの意味を簡単に定義します。
トークン(T) -->
アルナム(L)、
token_(Ls)、
!, % 単一解: 最長一致
{ atom_chars(T, [L|Ls]) }.
alnum(A) --> [A], { char_type(A, alnum) }.
token_([L|Ls]) --> alnum(L), token_(Ls).
token_([]) --> [].
サンプルクエリ
以下にいくつかの例を示します。
?- フレーズ(トークン(T), "GOLD" ).
T = 'ゴールド' .
?- フレーズ(トークン(T), "2" ).
T = '2' .
?- フレーズ(トークン(T), "GOLD 2" ).
偽。
最後の例は、空白をトークンの一部にできないことを明確にしています。
空白
次のシーケンスを空白と見なします。
スペース --> []。
スペース --> スペース、スペース。
スペース --> [S], { char_type(S, スペース) }.
解決
したがって、空白で区切られた一連のトークンは次のようになります。
トークン ([]) --> []。
tokens([T|Ts]) --> token(T)、スペース、tokens(Ts)。
以上です!
Ulrich Neumerkel の先見の明を使用して、この DCG を filesに透過的に適用できるようになりlibrary(pio)
ました。
ここにあるwumpus.data
:
$ 猫 wumpus.data
ゴールド 3 2
ウンパス 3 3
ピット 2 1
ピット 3 4
を使用phrase_from_file/2
して DCG をファイルに適用すると、次のようになります。
?-phrase_from_file(トークン(Ts)、「wumpus.data」)。
Ts = ['GOLD', '3', '2', 'WUMPUS', '3', '3', 'PIT', '2', '1', 'PIT', '3', '4' ] .
このようなトークンのリストから、たとえば再びDCGを使用して、必要なデータを簡単に取得できます。
データ([]) --> [].
data([D|Ds]) --> data_(D), data(Ds).
data_(gold(X,Y)) --> ['GOLD'], coords(X, Y).
data_(wumpus(X,Y)) --> ['WUMPUS'], coords(X, Y).
data_(pit(X,Y)) --> ['PIT'], coords(X, Y).
coords(X, Y) --> atom_number(X), atom_number(Y)。
atom_number(N) --> [A], { atom_number(A, N) }.
これらの DCG を一緒に使用して、次のことを行うことができます。
- ファイルまたは指定された文字リストをトークン化する
- トークンを解析して構造化データを作成します。
サンプルクエリ:
?-phrase_from_file(tokens(Ts), 'wumpus.data'),
フレーズ(データ(Ds)、Ts)。
Ts = ['GOLD', '3', '2', 'WUMPUS', '3', '3', 'PIT', '2', '1'|...],
Ds = [ゴールド(3, 2), ウンパス(3, 3), ピット(2, 1), ピット(3, 4)] .
この多彩なメカニズムの詳細については、dcgを参照してください。
1 SWI-Prolog には の古いバージョンが同梱されており、 を に設定する library(pio)
と動作しません。SWI-Prolog でこれを試したい場合は、Ulrich が提供するバージョンを直接使用してください。double_quotes
chars