(Пролог) Преобразование s-выражений Лиспа в термины Пролога

Я написал синтаксический анализатор на Прологе, который принимает токенизированный список и должен возвращать выражение, в котором переменная объединена со значением оцениваемого уравнения:

Tokens = ['(', is, v('X',3),'(', +, 1, 2, ')', ')' ]
Expr = (3 is 1 + 2)

В настоящее время мой парсер возвращает следующее:

Expr [is, _G32432, '(', +, 1, 2, ')'|_G19343]

У кого-нибудь есть идея, как я могу исправить этот парсер? Я включил код ниже:

%Definite Clause Grammar (DCG) for Lisp s-expressions
expression(N) --> atom(N).
expression(N) --> integer(N).
expression(N) --> variable(N).
expression(N) --> list(N).
list(N) --> ['('], sequence(N), [')'].
sequence(_) --> [].
sequence([H|T]) --> expression(H), sequence(T).
%atom(_) --> [].
atom(N) --> [N],{atom(N)}.
%variable(_) --> [].
variable(N) --> [v(_,N)],{var(N)}.
%integer(_) --> [].
integer(N) --> [N],{integer(N)}.    

evaluate(String, Expr):-
tokenize(String, Tokens),
expression(Expr,Tokens,[]),
write('Expression: '), write_term(Expr, [ignore_ops(true)]).

РЕДАКТИРОВАТЬ: Ниже приведена моя рабочая версия парсера:

expression(N) --> atom(N).    %an atom is a type of expression
expression(N) --> integer(N). %an integer is a type of expression
expression(N) --> variable(N). %a variable is a type of expression
expression(M) --> list(N),{M=..N}.  
list(N) --> ['('], sequence(N), [')'].   %a sequence within parens is a type of list
sequence([]) --> [].                 %a sequence can be empty
sequence([H|T]) --> expression(H), sequence(T).  %a sequence can be composed of an expression
% sequence([]) --> []. %and a sequence atom(_) --> [].
atom(N) --> [N],{atom(N),N \= '(', N \= ')'}. %parens are not atoms, but all other Prolog atoms 
% If N is a variable and it is within the v(Label,X) data structure,
% then it is a var in this grammar
variable(N) --> [v(_,N)],{var(N)}.
%variable(_) --> [].
%integer(_) --> [].
integer(N) --> [N],{integer(N)}.

person Dirigo    schedule 12.11.2014    source источник
comment
Предложения в комментарии ниже не решили мою проблему, к сожалению. Смотрите мое редактирование для окончательной исправленной версии.   -  person Dirigo    schedule 16.11.2014


Ответы (1)


Один из ваших входных токенов — [1]. Обратите внимание, что оно никогда не будет соответствовать вашему правилу [2], поскольку N — это целое число, а не переменная (также 'X' — это атом, а не переменная).

[1]   v('X',3)
[2]   variable(N) --> [v(_,N)],{var(N)}.

Изменение [2] на [3] устраняет эту проблему.

[3]   variable(N) --> [N], {var(N)}.

PS: Также убедитесь, что вы закрыли полученное выражение в базовом случае для sequence//1, заменив соответствующую строку на [4].

[4]   sequence([]) --> [].
person Wouter Beek    schedule 12.11.2014