【问题标题】:What DCG rules should be added?应该添加哪些 DCG 规则?
【发布时间】:2011-11-30 03:07:39
【问题描述】:

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

【问题讨论】:

  • 有什么想法吗?我试图添加“元素(E)-> [E]”,但它抛出异常......
  • 感兴趣的:SWI-Prolog SGML/XML parser

标签: prolog grammar dcg


【解决方案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 

【讨论】:

  • 感谢您的回答!我实际上添加了以下规则:elements([X:N]) --> [X,':',N]。元素([X 'in' Y:N]) --> [X,'in',Y,':',N]。元素([X:N 'in' Y:M]) --> [X,':',N,'in',Y,':',M].
  • 那行得通。看起来像是 IDE 或其他代码处理工具的一部分。
猜你喜欢
  • 2018-07-05
  • 1970-01-01
  • 2017-02-13
  • 2017-04-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多