我正在使用Prolog DCG为一种简单的编程语言构建一个词法分析器/解析器,该词法器使用DCG参数构建令牌/语法树列表,例如
symbol(semicolon) --> ";".
symbol(if) --> "if".
然后使用 DCG 规则的这些参数构建语法树。
但是,当解析变量和数字(这种语言中只有整数)时,我遇到了一个颠簸,我需要 DCG 参数更加动态,例如
symbol(number(X)) --> X, {integer(N)}.
从本质上讲,我需要 DCG 参数基本上是从它实际解析的内容生成的。有没有办法做到这一点?如果没有,有什么好的解决方法?
编辑:作为一个具体的例子,我有规则
symbol(num(N)) --> {number_codes(N,C)}, C.
查询时我需要输出N=7
phrase(symbol(num(N)),"7").
我在这里看到三个问题。
-
phrase/2
想要在代码列表上运行。从版本 7 开始,SWI 具有不支持 DCG 的本机字符串类型。因此,您现在必须求助于这个稍微不方便的公式:atom_codes("if", Codes), phrase(symbol(X), Codes)
-
通常,您希望从输入中剥离某些内容,然后将其交给某个纯Prolog谓词来执行某些操作。换句话说,像这样:
symbol(num(N)) --> [C], { number_codes(N, [C]) }. ?- atom_codes(9, X), phrase(symbol(S), X). X = [57], S = num(9).
当然,这仅适用于个位数的数字,这可能不是您想要的,所以......
-
您可能应该像这样使用
dcg/basics.pl
中的代码::- use_module(library(dcg/basics)). symbol(num(N)) --> integer(N). ?- atom_codes(973, X), phrase(symbol(S), X). X = [57, 55, 51], S = num(973).
或者您可以使用源代码进行复制/粘贴操作。您可能会注意到,其中的所有 DCG 规则要么从调用另一个 DCG 规则开始,要么消耗一些输入,然后执行其他操作;您可能不想生成某些内容,然后在输入中查找它。