1

好的,所以我正在使用 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, '>'].

所以规则不能处理诸如“p1:1 in main: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))
               )))).
4

1 回答 1

0

我对 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 
于 2010-11-09T13:44:29.387 回答