好的,所以我使用prolog来构建一个简单的xml解析器。我有以下xml文件:
<ip> <line> 7 </line> <envt> p1:1 in main:1 </envt> </ip>
<contour>
<name> main:1 </name>
<items>
<item> <var> x:int </var> <val> 2 </val> </item>
<item> <var> y:int </var> <val> 2 </val> </item>
</items>
<rpdl> system </rpdl>
<nested>
<contour>
<name> p1:1 </name>
<items>
<item> <var> y:int </var> <val> 0 </val> </item>
<item> <var> q:proc </var> <val> p2 in main:1 </val> </item>
</items>
<rpdl> <line> 21 </line> <envt> main:1 in root:1 </envt> </rpdl>
</contour>
</nested>
</contour>
</program_state>
在Prolog中我使用以下DCG规则:
xml([E]) --> element(E).
xml([E|L]) --> element(E), xml(L).
element(E) --> begintag(N), elements(L), endtag(N), {E =.. [N|L]}.
elements(L) --> xml(L).
elements([E]) --> [E].
begintag(N) --> ['<', N, '>'].
endtag(N) --> ['<', '/', N, '>'].
因此规则无法处理“main:1中的p1:1”,“x:int”,“main:1”之类的内容。我实际上试图将这些东西改成“p1”,“x”,“main”,并且解析器工作得很好。现在应该添加哪些规则以便解析器可以处理不规则的令牌?
解析树将是这样的:
program_state(
ip(line(7), envt(p1:1 in main:1)),
contour(name(main:1),
items(item(var(x:int),val(2)),
item(var(y:int),val(2))),
rpdl(system),
nested(contour( name(p1:1),
items(item(var(y:int),val(0)),
item(var(q:proc),val(p2 in main:1))),
rpdl(line(21),envt(main:1 in root:1)),
))))
以下是我得到的:
program_state(
ip(line(7), envt(p1)),
contour(name(main),
items(item(var(x), val(2)),
item(var(y), val(2))),
rpdl(system),
nested(contour(name(p1),
items(item(var(y), val(0)),
item(var(q), val(p2))),
rpdl(line(21), envt(main))
)))).
答案 0 :(得分:1)
我将XML标记化,将其提供给解析器并且工作正常。验证输入:需要引用带冒号(:)的符号;否则他们代表module_name:module_specific_symbol
。这是输入:
?- listing(input).
input([<, program_state, >, <, ip, >, <, line, >, '7', <, /, line, >, <, envt, >, ['p1:1', in, 'main:1'], <, /, envt, >, <, /, ip, >, <, contour, >, <, name, >, 'main:1', <, /, name, >, <, items, >, <, item, >, <, var, >, 'x:int', <, /, var, >, <, val, >, '2', <, /, val, >, <, /, item, >, <, item, >, <, var, >, 'y:int', <, /, var, >, <, val, >, '2', <, /, val, >, <, /, item, >, <, /, items, >, <, rpdl, >, system, <, /, rpdl, >, <, nested, >, <, contour, >, <, name, >, 'p1:1', <, /, name, >, <, items, >, <, item, >, <, var, >, 'y:int', <, /, var, >, <, val, >, '0', <, /, val, >, <, /, item, >, <, item, >, <, var, >, 'q:proc', <, /, var, >, <, val, >, [p2, in, 'main:1'], <, /, val, >, <, /, item, >, <, /, items, >, <, rpdl, >, <, line, >, '21', <, /, line, >, <, envt, >, ['main:1', in, 'root:1'], <, /, envt, >, <, /, rpdl, >, <, /, contour, >, <, /, nested, >, <, /, contour, >, <, /, program_state, >]).
true.
调用解析器的方式列表:
?- listing(run).
run :-
consult('input.db'),
input(A),
phrase(xml(B), A),
write(B),
nl.
true.
解析器运行列表:
?- run.
% input.db compiled 0.00 sec, 2,768 bytes
[program_state(ip(line(7),envt([p1:1,in,main:1])),contour(name(main:1),items(item(var(x:int),val(2)),item(var(y:int),val(2))),rpdl(system),nested(contour(name(p1:1),items(item(var(y:int),val(0)),item(var(q:proc),val([p2,in,main:1]))),rpdl(line(21),envt([main:1,in,root:1]))))))]
true