我使用 assert(....)将给定的上下文无关语法插入到数据库中 如果语法类似于
S-->a,S,b
S-->c
将该语法插入数据库中。 我必须写一个dcg来为数据库中的cfg生成句子。 例如,如果我以这种方式定义dcg myDcg('S',str),则应调用'S'(非终端)或替换< / em>通过 aSb 或 c | d 左右。
问题是,每当遇到非终端('S')生成句子时,我如何通过数据库中的事实来调用/替换'S'。
希望你理解我的问题,如果没有,我会尝试编辑这个问题。
下面(示例代码)是我想要做的 这不是dcg。
myGrammar([], []):-!.
myGrammar([T|Rest], [T|Sentence]):-
myGrammar(Rest, Sentence).
myGrammar([NT|Rest], Sentence):-
grammar(NT, Rest1),
append(Rest1,Rest, NewRest),
myGrammar(NewRest, Sentence).
每当遇到终端时,都应打印出来,当遇到非终端时,它会回溯。
答案 0 :(得分:2)
我假设您最近开始使用Prolog。 是的,您可以将内容置于数据库中,但这不是您首先要做的常见事情。当您对基本语言感到安全时,您将希望稍后使用该功能。
您通常要将语法写入myfirstgrammar.pl
等文件,然后将该文件加载到Prolog系统中。
有关语法的详细信息,请参阅this recent thread。
答案 1 :(得分:2)
在谓词mygrammar/2
中,第一个参数中有一个非终端和终端列表,第二个参数中有一个终端列表。如果第二个参数是第一个参数的形式,它应该可能成功。所以你在这里拥有的是DCG的元解释器。一些建议:
您的标记生成器当前生成[grammar('S',[a,'S',b]),grammar('S',[....]),..].
让它生成[grammar('S',[t(a),nt('S'),t(b)]),grammar('S',[....]),..]
。以这种方式,很明显什么是终端,什么是非终端。而且,哦,删除它!。
myGrammar([], []).
myGrammar([t(T)|Rest], [T|Sentence]):-
myGrammar(Rest, Sentence).
myGrammar([nt(NT)|Rest], Sentence):-
grammar(NT, Rest1),
append(Rest1,Rest, NewRest),
myGrammar(NewRest, Sentence).
DCGs,btw比这个解释器更通用。
非终端和终端之间的实际分类必须由分词器完成。
uppercasecode(C) :-
between(0'A,0'Z,C).
lowercasecode(C) :-
between(0'a,0'z,C).
如果您使用字符(单字符原子),您将使用char_code(Char, Code)
在它们之间进行转换。
完整的Unicode支持仍处于起步阶段。它非常棘手,因为所有这些特殊情况下的字符如Ⓐ是大写但仍然不能成为标识符的一部分。但是目前你可以在SWI中做到这一点。
uppercasecode(C) :-
'$code_class'(C,upper),
'$code_class'(C,id_start).
lowercasecode(C) :-
'$code_class'(C,id_start),
'$code_class'(C,id_continue),
\+ '$code_class'(C,upper).
更新:与此同时,char_type/2
和code_type/2
用于此目的。
uppercasecode(C) :-
code_class(C, upper),
code_class(C, prolog_var_start).