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。