关于序言:DCG,右递归以及如何清楚地表达它

 2020-10-18 

DCG, right-recursion and how to express it clearly

我已经阅读了很多建议的问题,但是我现在仍然束手无策,我正在尝试编写一个简单的Lisp s表达式解析器,并且我想不出如何解决s表达式的递归性质。把我的大脑打结!

这就是我所拥有的,输入是来自我的lexer模块的源文件中的标记化术语的列表,其工作正常:(顺便说一下,GNU Prolog)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
lisp_term(T) -->
        (
     null(T)
        ;
         token(T)
        ;
         sexp_open(_), lisp_term(T2), sexp_close(_), {T = lnode(T2)}
        ).

lisp_term(T) --> [], {T=end}.


sexp_open(Pos)  --> [popen(Pos)].
sexp_close(Pos) --> [pclose(Pos)].

token(token(Pos,Token)) --> [token(Pos,Token)].

null(null(Pos1)) --> [popen(Pos1), pclose(_)].

这是我的通话代码...

1
2
3
4
5
lisplex('../test.lisp',X),
lexpp(X),
phrase(lisp_term(A), X, Y),
format("Result:    ~w~n", [A]),
format("Remainder: ~w~n", [Y]).

词法分析器的输出是这样的列表,来源:"(hello)"

1
[popen(pos(1,1)),token(pos(1,2),[h,e,l,l,o]),pclose(pos(1,7))]

我一直束手无策,试图弄清楚如何处理类似这样的表达式:

1
2
(defun whizzle (a1 b2)
    (munge (* 10 a1) (+ b2 a1)))

也就是说,通常如何处理将词法分析器流转换为解析树。您可以看到我的DCG规则正在尝试这样做。

我将非常感谢您提供的帮助和指向一些好东西的指南,以阅读或提出有关如何更好地理解应对右递归情况的建议。我已经在Prolog上教了我几个月,并且非常喜欢它,但是我仍然坚持能够继续对DCG-s和类似情况的理解。

谢谢,
肖恩。


我认为您没有名单! 尝试(未试用)

1
2
3
4
5
6
7
lisp_term(T) --> token(T).
lisp_term(lnode(T)) -->
     sexp_open(_), lisp_list(T), sexp_close(_).

lisp_list([H|T]) -->
     lisp_term(H), lisp_list(T).
lisp_list([]) --> [].

然后看看Markus Triska页面上的Lisprolog。