Question

okay, so I am using prolog to build a simple xml parser. And I have the following xml file:

<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>

and in Prolog I use the following DCG rules:

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, '>'].

so the rules can't handle things like "p1:1 in main:1", "x:int", "main:1". I actually tried to change those things into "p1", "x", "main", and the parser works perfectly fine. Now what rules should I add so that the parser could handle the irregular tokens?

The parse tree will be something like this:

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)),
                  ))))

and the following is what I get:

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))
               )))).
Was it helpful?

Solution

I tokenized the XML, fed it to the parser and it worked fine. Verify the input: Symbols with a colon(:) in them need to be quoted; otherwise they represent module_name:module_specific_symbol. Here's the input:

?- 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.

A listing of the how the parser is invoked:

?- listing(run).
run :-
    consult('input.db'),
    input(A),
    phrase(xml(B), A),
    write(B),
    nl.

true.

A listing of the parser run:

?- 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 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top