在您的谓词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).
DCG,顺便说一句,比这个解释器更通用一点。
非终端和终端之间的实际分类必须由分词器完成。
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).