简体   繁体   English

序言中的语法

[英]Grammar in prolog

I want to be able to translate arrays like [int(2), sep(<), int(1), sep(-), id(N)] into conditions (in this example [int(2) < int(1)-id(N)] ) using grammar. 我希望能够将[int(2), sep(<), int(1), sep(-), id(N)]等数组转换为条件(在此示例中, [int(2) < int(1)-id(N)] )使用语法。 I have the grammar below: 我的语法如下:

cond(_, A > B) --> expr(_,A), [sep(>)], expr(_,B).
cond(_, A < B) --> expr(_,A), [sep(<)], expr(_,B).
expr(_, int(X)) --> [int(X)].
expr(_, id(X)) --> [id(X)].
expr(_, X + Y) --> expr(_,X), [sep(+)], expr(_,Y).
expr(_, X - Y) --> expr(_,X), [sep(-)], expr(_,Y).

What I don't understand is the fact that if I have the array: [int(2), sep(>), int(1), sep(+), id(N)] everything is fine, the condition is translated correctly. 我不明白的事实是,如果我有以下数组: [int(2), sep(>), int(1), sep(+), id(N)]一切都很好,条件会被翻译正确地。 I make some changes then, replacing + by - or > by < (take account of the fact that in my grammar > is one line over < , same as + and - ) and this isn't translated, it falls into infinite loop: 我做出一些改变的话,更换+->< (考虑的事实是,在我的语法>是通过一条线路< ,相同+-这是没有翻译,就陷入无限循环:

Call:  (18)  ? [sep(-), id(N)]=[sep(+)|_G2290032]creep
Fail:  (18)  ? [sep(-), id(N)]=[sep(+)|_G2290032]creep

It is always comparing to line with sep(+) . 它总是与sep(+)进行比较。 What is wrong in this grammar? 这个语法有什么问题?

--EDIT added tracing --EDIT添加了跟踪

phrase(cond(_, X), [int(2), sep(<), int(1), sep(-),id(N)]).
   Call:  (10)  ? cond(_G2313, _G2314, [int(2), sep(<), int(1), sep(-), id(_G2336)], [])creep
   Call:  (11)  ? expr(_L254, _G2482, [int(2), sep(<), int(1), sep(-), id(_G2336)], _L235)creep
   Exit:  (11)  ? expr(_L254, int(2), [int(2), sep(<), int(1), sep(-), id(_G2336)], [sep(<), int(1), sep(-), id(_G2336)])creep
   Call:  (11)  ? [sep(<), int(1), sep(-), id(_G2336)]=[sep(>)|_G2488]creep
   Fail:  (11)  ? [sep(<), int(1), sep(-), id(_G2336)]=[sep(>)|_G2488]creep
   Redo:  (11)  ? expr(_L254, _G2482, [int(2), sep(<), int(1), sep(-), id(_G2336)], _L235)creep
   Call:  (12)  ? expr(_L279, _G2485, [int(2), sep(<), int(1), sep(-), id(_G2336)], _L260)creep
   Exit:  (12)  ? expr(_L279, int(2), [int(2), sep(<), int(1), sep(-), id(_G2336)], [sep(<), int(1), sep(-), id(_G2336)])creep
   Call:  (12)  ? [sep(<), int(1), sep(-), id(_G2336)]=[sep(+)|_G2491]creep
   Fail:  (12)  ? [sep(<), int(1), sep(-), id(_G2336)]=[sep(+)|_G2491]creep
   Redo:  (12)  ? expr(_L279, _G2485, [int(2), sep(<), int(1), sep(-), id(_G2336)], _L260)creep
   Call:  (13)  ? expr(_L304, _G2488, [int(2), sep(<), int(1), sep(-), id(_G2336)], _L285)creep
   Exit:  (13)  ? expr(_L304, int(2), [int(2), sep(<), int(1), sep(-), id(_G2336)], [sep(<), int(1), sep(-), id(_G2336)])creep
   Call:  (13)  ? [sep(<), int(1), sep(-), id(_G2336)]=[sep(+)|_G2494]creep
   Fail:  (13)  ? [sep(<), int(1), sep(-), id(_G2336)]=[sep(+)|_G2494]creep
   Redo:  (13)  ? expr(_L304, _G2488, [int(2), sep(<), int(1), sep(-), id(_G2336)], _L285)creep
   Call:  (14)  ? expr(_L329, _G2491, [int(2), sep(<), int(1), sep(-), id(_G2336)], _L310)creep
   Exit:  (14)  ? expr(_L329, int(2), [int(2), sep(<), int(1), sep(-), id(_G2336)], [sep(<), int(1), sep(-), id(_G2336)])creep
   Call:  (14)  ? [sep(<), int(1), sep(-), id(_G2336)]=[sep(+)|_G2497]creep
   Fail:  (14)  ? [sep(<), int(1), sep(-), id(_G2336)]=[sep(+)|_G2497]creep
   Redo:  (14)  ? expr(_L329, _G2491, [int(2), sep(<), int(1), sep(-), id(_G2336)], _L310)creep
   Call:  (15)  ? expr(_L354, _G2494, [int(2), sep(<), int(1), sep(-), id(_G2336)], _L335)creep
   Exit:  (15)  ? expr(_L354, int(2), [int(2), sep(<), int(1), sep(-), id(_G2336)], [sep(<), int(1), sep(-), id(_G2336)])creep
   Call:  (15)  ? [sep(<), int(1), sep(-), id(_G2336)]=[sep(+)|_G2500]creep
   Fail:  (15)  ? [sep(<), int(1), sep(-), id(_G2336)]=[sep(+)|_G2500]
   ...

As suggested by @TomasBy, left recursion in non terminal expr//2 leads to non termination. 如@TomasBy所建议,在非终端expr // 2中的左递归导致非终止。 In SWI-Prolog there is library( tabling ), just import it and declare expr//2 as tabled. 在SWI-Prolog中有library( tabling ),只需将其导入并声明表中的expr // 2。

:- use_module(library(tabling)).
:- table expr//2.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM