在Prolog中声明一个谓词以与DCG一起使用时,我做错了什么?

在Prolog中声明一个谓词以与DCG一起使用时,我做错了什么?,prolog,grammar,dcg,Prolog,Grammar,Dcg,我使用以下方法检查字符串是否可用于语法: id(ID) :- atom_chars(ID, [H|T]), is_alpha(H), ensure_valid_char(T). ensure_valid_char([H|T]) :- H == '_'; is_alpha(H); atom_number(H, _), ensure_valid_char(T). 它基本上只是检查它是否以字母字符开头,然后可以是字母数字或下划线 不过,我似乎

我使用以下方法检查字符串是否可用于语法:

id(ID) :-
    atom_chars(ID, [H|T]),
    is_alpha(H),
    ensure_valid_char(T).

ensure_valid_char([H|T]) :-
    H == '_';
    is_alpha(H);
    atom_number(H, _),
    ensure_valid_char(T).
它基本上只是检查它是否以字母字符开头,然后可以是字母数字或下划线

不过,我似乎不知道如何使用我的DCG/语法来实现这一点

这是将使用谓词的当前结构:

typeID(Result) --> ['int'], id(ID), {
    Result = ['int', ID]
}.
基本上,我说的是
typeID
是一个整数类型声明,后跟一个标识符(
intfoo
就是一个例子),然后我将它格式化成一个列表并“返回”

但在本例中,它表示“id”是一个未定义的谓词。我如何使用它,以便我仍然能够访问ID持有的内容,以便能够格式化它,并且仍然确保它是使用谓词的ID

如果我尝试:

id(ID) --> {
    atom_chars(ID, [H|T]),
    is_alpha(H),
    ensure_valid_char(T),
    ID = ID 
}.
我得到的错误是:

atom_chars/2: Arguments are not sufficiently instantiated

请使用更易读的名称。Prolog惯例是使用下划线以提高可读性

这是因为使用下划线会使名称更长,更容易阅读,但使用混合CAPS不会使您的代码不可重复

第二,请避免不必要的目标。像
ID=ID
这样的目标始终有效,因此您也可以删除它

第三,在描述DCGs中最长匹配时,一种常见的模式是使用如下子句:

symbol([A|As]) -->
    [A],
    { memberchk(A, "+/-*><=") ; code_type(A, alpha) },
    symbolr(As).

symbolr([A|As]) -->
    [A],
    { memberchk(A, "+/-*><=") ; code_type(A, alnum) },
    symbolr(As).
symbolr([]) --> [].
symbol//1
的最长匹配将是第一个解决方案


所有这些都要求将序言标志
双引号设置为
code

分号的优先级高于逗号

?- (N=(',') ; N=(';')), current_op(P,T,N).
N =  (','),
P = 1000,
T = xfy ;
N =  (;),
P = 1100,
T = xfy.
然后确保\u valid\u char/1没有您期望的结构。应该是

ensure_valid_char([H|T]) :-
    ( H == '_' ;
      is_alpha(H) ;
      atom_number(H, _)  % ugly 
    ),
    ensure_valid_char(T).
还有一个更简单的问题:您缺少递归的基本情况

ensure_valid_char([]).
ensure_valid_char([]).