2010-07-19 18 views
10

Tôi có phân tích cú pháp biểu hiện đơn giản như sau:số Parsing với nhiều chữ số trong Prolog

expr(+(T,E))-->term(T),"+",expr(E). 
expr(T)-->term(T). 

term(*(F,T))-->factor(F),"*",term(T). 
term(F)-->factor(F). 

factor(N)-->nat(N). 
factor(E)-->"(",expr(E),")". 

nat(0)-->"0". 
nat(1)-->"1". 
nat(2)-->"2". 
nat(3)-->"3". 
nat(4)-->"4". 
nat(5)-->"5". 
nat(6)-->"6". 
nat(7)-->"7". 
nat(8)-->"8". 
nat(9)-->"9". 

Tuy nhiên điều này chỉ hỗ trợ số 1 chữ số. Làm cách nào để phân tích cú pháp các số có nhiều chữ số trong trường hợp này?

+0

Bạn đang sử dụng prolog nào? Dones của tôi không có "->" nghĩ iirc. (SWI-Prolog) – InsertNickHere

+0

Tôi đang sử dụng SWI-Prolog, quá ^^ – ubuntudroid

+0

Huh. Nó nên là: - thay vào đó? * scratchhead * – InsertNickHere

Trả lời

9

Sử dụng biến tích lũy và chuyển các biến đó trong các cuộc gọi đệ quy. Trong phần sau, A và A1 là bộ tích lũy.

digit(0) --> "0". 
digit(1) --> "1". 
% ... 
digit(9) --> "9". 

nat(N) --> digit(D), nat(D,N). 
nat(N,N) --> []. 
nat(A,N) --> digit(D), { A1 is A*10 + D }, nat(A1,N). 

để khởi tạo bộ tích lũy bằng cách tiêu thụ chữ số vì bạn không muốn khớp với chuỗi trống.

+0

@ubuntodroid: Tôi nghĩ đây là một giải pháp tốt nếu bạn phải tự mình thực hiện phân tích cú pháp số. Tôi không biết nếu có một vị ngữ để phân tích cú pháp số tự nhiên theo mặc định trong Prolog. Mã cũng có thể được giảm nếu người ta có thể làm phép tính số học là "0" -> 0, "1" -> "0" + 1, ... trong Prolog. – thequark

+0

@thequark: Tôi không biết bất kỳ vị từ nào như vậy. 'atom_char/2' có thể được sử dụng, nhưng nó sẽ không được đẹp. Bạn cũng có thể viết một vị từ 'digit_int/2' với giá trị ASCII là '0' được mã hóa cứng (yuck). –

-3

Bạn có thể cung cấp đầu vào mẫu không?

Tôi nghĩ rằng đây sức công việc:

nat(N)-->number(N). 

Nếu thất bại thử:

nat(N)-->number(N),!. 

Các! là một vết cắt nó dừng sự thống nhất. Bạn có thể đọc về nó trong sách/hướng dẫn.

+0

Một số đầu vào mẫu có thể là expr (E, "2 * 14 + 3", ""). Mã bạn cung cấp dẫn đến thông báo lỗi cho tôi biết rằng số/3 là một quy trình không xác định và chỉ số/1 được biết. Tôi nghĩ về một DGC-khoản để giải quyết vấn đề của tôi, nhưng tôi đã không thể có được một làm việc. – ubuntudroid

+0

'số/1' là một biến vị ngữ thông thường, không phải là vị từ DCG. Bên cạnh đó, nó không thành công nếu đầu vào của nó không phải là mặt đất (là một biến). –

-1
nat(0). 
nat(N):-nat(N-1). 

Nhưng bạn sử dụng cú pháp mà tôi không biết (xem nhận xét của tôi ở trên).