【问题标题】:Expanding DCGs in Prolog在 Prolog 中扩展 DCG
【发布时间】:2020-02-13 16:13:42
【问题描述】:

我正在编写一个代码生成器,它将定句语法转换为其他语法符号。为此,我需要扩展一个语法规则:

:- initialization(main).

main :- 
        -->(example,A),writeln(A).
% this should print ([a],example1), but this is a runtime error

example --> [a],example1.
example1 --> [b].

-->(example, A) 并没有扩展规则,即使-->/2 似乎在这里定义。有没有其他方法可以访问 DCG 语法规则的定义?

【问题讨论】:

  • @GuyCoder listing(example) 不打印 [a],example1。它改为打印example(A, A). example([a|A], B) :- example(A, B)
  • 你为什么要这个?您正在干扰内置/内置机制。为什么不使用其他运算符?
  • @false 我已经写了好几个DCG语法了,所以我想把它们转换成CHR grammars,而不需要手动重写。
  • 一举就能更好地转换该文件。

标签: prolog swi-prolog dcg


【解决方案1】:

这是对您的预期以及您遇到问题的原因的猜测。它只是让我烦恼,因为我知道你很聪明,应该能够连接来自 cmets 的点。 (发布时评论已删除,但 OP 确实看到了。)

这是 SWI-Prolog 特有的。

加载 Prolog 代码时,它会自动进行术语扩展,如 expand.pl 中所述。

任何带有--> 的子句都将根据dcg_translate_rule/2 的规则进行扩展。所以当你在加载后的代码上使用listing/1 时,带有--> 的子句已经被扩展了。所以AFAIK你看不到([a],example1)这是加载之前的代码然后是术语扩展,但是example([a|A], B) :- example(A, B)是加载和术语扩展之后的代码。

获得所需代码的唯一方法是在加载过程中关闭术语扩展,但本应扩展的代码不会,代码将无法运行。

您也可以尝试查找加载代码的来源,但我也认为这不是您想要做的。

基于此I'm writing a code generator that converts definite clause grammars to other grammar notations.,您可能需要替换 dcg_translate_rule/2 的代码,或者在加载时和术语扩展之前拦截代码。

HTH


至于与-->(example,A),writeln(A). 相关的错误,那是因为那不是有效的DCG 子句。

【讨论】:

  • 在某些情况下,可以将扩展子句转换回 DCG,但我还没有找到方法。
【解决方案2】:

正如您在 cmets 上所写,如果要将 DCG 转换为 CHR,则需要在将 DCG 默认扩展为子句之前应用转换。例如,假设您的代码保存到grammars.pl 文件:

?- assertz(term_expansion((H --> B), '--->'(H,B))).
true.

?- assertz(goal_expansion((H --> B), '--->'(H,B))).
true.

?- [grammars].
[a],example1
true.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多