微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在序言中编写语法并且无法使其正常工作

如何解决在序言中编写语法并且无法使其正常工作

这是一个课堂作业,但我不知道如何解决我的问题。 我写了以下内容

codeArea.textproperty().addListener(new changelistener<String>()
    {
        @Override
        public void changed(ObservableValue<? extends String> observableValue,String s,String s2) {
            
            
            String curr = "";
            String currFinal = "";
            for (int i = codeArea.getAnchor(); i > 0; i--) {
                if (codeArea.getText().charat(i) == '\n' || codeArea.getText().charat(i) == ' ') {
                    break;
                }else {
                    curr += codeArea.getText().charat(i);
                }
            }
            
            for (int i = curr.length()-1; i >= 0; i--) {
                currFinal += curr.charat(i);
            }
            
            if (currFinal != "") {
                ArrayList<String> fil = new ArrayList<String>();
                for (int i = 0; i < keyphrases.length; i++) {
                    if (keyphrases[i].contains(currFinal)) {
                        fil.add(keyphrases[i]);
                    }
                }
                System.out.println("Fil " + fil);
                if (popup != null) {
                    popup.hide();
                }
                if (fil.size() > 0) {
                    
                    
                    
                    ListView lop = new ListView();
                    for (int i = 0; i < fil.size(); i++) {
                        lop.getItems().add(fil.get(i));
                    }
                    
                    popup = new Popup();
                 
                    lop.setMaxHeight(80);
                    popup.getContent().addAll(lop);
                    popup.show(codeArea,codeArea.getCaretBounds().get().getMaxX(),codeArea.getCaretBounds().get().getMaxY());
                    codeArea.requestFocus();
                    
                }
                codeArea.requestFocus();
            }else { 
                if (popup != null) {
                    popup.hide();
                }
            }
        }
            
            
    });

我做了一个跟踪:

sentence(S0,S):- f(S0,S); t(S0,S1),n(S1,S2),t(S2,S).
f(S0,S):- termIf(S0,pLeft(S1,b(S2,S3),pRight(S3,S4),termThen(S4,S5),termBegin(S5,S6),sentence(S6,S7),termEnd(S7,S); termIf(S0,termElse(S7,S8),sentence(S8,S9),termEnd(S9,S).
b(S0,S):- t(S0,e(S1,S). 
termIf(S0,S) :- S0=[if|S].
termThen(S0,S):- S0=[then|S].
termBegin(S0,S):- S0=[begin|S].
termEnd(S0,S):- S0=[end|S].
termElse(S0,S):- S0=[else|S].
pLeft(S0,S):- S0=['('|S].
pRight(S0,S):- S0=[')'|S].
t(S0,S):- S0=[x|S].
t(S0,S):- S0=[y|S].
t(S0,S):- S0=[z|S].
t(S0,S):- S0=[1|S].
t(S0,S):- S0=[0|S].
e(S0,S):- S0=[>|S].
e(S0,S):- S0=[<|S].
n(S0,S):- S0=[+|S].
n(S0,S):- S0=[-|S].
n(S0,S):- S0=[=|S].

我认为当句子被调用时它显然失败了,但它得到了一个它无法处理的 [[x,=,1],end] 。我认为显而易见的答案是 [x,1] 是列表的第一个元素,但我不知道如何将该元素传递给句子,以便正确处理事情。我很难过。

解决方法

该代码需要一个扁平的终端列表,但其中有一个嵌套的 [x,=,1]。你想要的是

?- sentence([if,'(',x,>,')',then,begin,1,end],X).
X = []
Yes (0.00s cpu,solution 1,maybe more)
No (0.00s cpu)
,

你怎么能自己定位错误?一种可能性是概括您的查询。只要您的程序是纯单调的,以下内容就成立:

如果通用查询失败,那么更专业的查询也会失败

因此,这种概括与失败相关

通过用 _ 替换条款,我获得了以下仍然失败的查询(另外,我将您的代码翻译成 DCG 形式)...

?- phrase(sentence,[if,[x,1],end]).
false.

?- phrase(sentence,[_,_,[_|  _  ]|   _]).
false.

sentence--> f ; t,n,t.

(加上 CapelliC 给出的其余规则)

从这个概括我们看到,没有一个句子的第 9 个元素是一个至少有一个元素的列表。

另请注意,您现在可以枚举所有句子!

?- length(L,_),phrase(sentence,L).
   L = [x,+,x]
;  L = [x,y]
;  L = [x,z]
;  L = [x,1]
;  L = [x,0]
;  ... 
,

问题,正如@jschimpf 所指出的,是我们在初始调用中混合了两个描述级别。列表是元数据,用 DCG 符号重写语法更明显。一旦修正了原始公式(是 sentence--> f; t,t.),测试 ?- g. 就通过了。


sentence--> f; [L],{phrase((t,t),L)}.
f--> termIf,pLeft,b,pRight,termThen,termBegin,sentence,termEnd.
f--> termIf,termElse,termEnd.
b--> t,e,t.
termIf--> [if].
termThen--> [then].
termBegin--> [begin].
termEnd--> [end].
termElse--> [else].
pLeft--> ['('].
pRight--> [')'].
t--> [x].
t--> [y].
t--> [z].
t--> [1].
t--> [0].
e--> [>].
e--> [<].
n--> [+].
n--> [-].
n--> [=].

g :- phrase(sentence,end]).

编辑

现在我们可以修复原始代码中的问题,其中 sentence/2 具有 DCG 分配给 phrase/2 的角色:

sentence(S0,S):-
  S0=[H|T],(  \+is_list(H)
  -> f(S0,S)
  ;  t(H,S1),n(S1,S2),t(S2,[]),S=T
  ).

编辑 我已经提出了我认为对句子/2 更有指导意义的更正,但我们可以避免“不纯”的 if/then/else 结构,例如

sentence(S0,S):-
  f(S0,S);S0=[H|S],H=[_|_],t(H,[]).

应该可以工作(未经测试...)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。