我目前正在尝试建立一个小程序,用于使用 DCG 在 SWI Prolog 中接受 IPv4 点状四边形字符串(在假期走出舒适区?是的,我可以!这可能需要我再花一个小时左右的时间,但也许读者中的某个人已经准备好了。在这种情况下,我可以攻击IPv6地址字符串。
我将尝试在此片段上回答 SWISH
的问题这是代码,以防链接不稳定...
:- use_module(library(dcg/basics)).
atom_ipv4(A, IPV4) :- atom_codes(A, Cs), phrase(ipv4(IPV4), Cs).
ipv4(D) -->
dotted(D).
ipv4(range(D, R)) -->
dotted(D), "/", integer(R).
dotted(address(A, B, C, D)) -->
octet(A), ".", octet(B), ".", octet(C), ".", octet(D).
octet(A) --> integer(A), {A < 256}.
注意:当然,规范比此代码片段捕获的规范更复杂,因为它允许十六进制,以及更多...我的目的是指出库的可用性(DCG/基础(
答案 #2:
% Is the atom 'X' a valid IPv4 address?
% Transform the atom 'X' into a list of character codes, which is then processed
is_ipv4(X) :- string_codes(X,Codes), phrase(ipv4, Codes).
% Testing the above
test :- is_ipv4('127.0.0.1'),
is_ipv4('255.255.255.255'),
is_ipv4('10.10.10.1'),
is_ipv4('0010.00010.000.0000'),
+is_ipv4('256.0.0.1'),
+is_ipv4('12.0.'),
+is_ipv4('').
% ----------------------
% Use Definite Clause Grammer to parse a list of character codes
% Subelements can be queried like this:
% phrase(quadpart, `255`, []).
% phrase(pdigits(X,Y), `123`, []).
ipv4 --> quadpart, dot, quadpart, dot, quadpart, dot, quadpart.
dot --> `.`.
quadpart --> pdigits(_,Q), { Q < 256 }.
pdigits(UpPower,UpValue) --> pdigit(Value), !, pdigits(DownPower, DownValue), { UpValue is DownPower*Value+DownValue, UpPower is DownPower*10 }.
pdigits(1,0) --> [].
pdigit(Value) --> [D], { code_type(D, digit(Value)) }.
% ---------------------