2010-07-19 6 views
10

Ich habe die folgenden einfachen Ausdruck Parser:Parsing Zahlen mit mehreren Stellen in 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". 

jedoch nur diese unterstützen 1-stellige Zahlen. Wie kann ich in diesem Fall Zahlen mit mehreren Ziffern analysieren?

+0

Welchen Prolog verwenden Sie? Meine hat nicht das "->" Think iirc. (SWI-Prolog) – InsertNickHere

+0

Ich benutze auch SWI-Prolog ^^ – ubuntudroid

+0

Huh. Shouldent es sein: - stattdessen? * scratchhead * – InsertNickHere

Antwort

9

Verwenden Sie Akkumulatorvariablen und übergeben Sie diese in rekursiven Aufrufen. Im Folgenden sind A und A1 der Akkumulator.

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). 

Beachten Sie, dass die erste nat Klausel des Speichers initialisiert durch eine Ziffer raubend, weil Sie nicht wollen, die leere Zeichenkette übereinstimmen.

+0

@ubuntodroid: Ich denke, das ist eine gute Lösung, wenn Sie die Zahlenanalyse selbst implementieren müssen. Ich weiß nicht, ob es ein Prädikat gibt, natürliche Zahlen in Prolog standardmäßig zu analysieren. Der Code kann auch reduziert werden, wenn man in Prolog Zeichenarithmetik durchführen kann, die "0" -> 0, "1" -> "0" + 1, ... ist. – thequark

+0

@thequark: Ich kenne kein solches Prädikat. 'atom_char/2' kann verwendet werden, aber es wäre nicht schön. Sie könnten auch ein Prädikat 'digit_int/2' mit dem ASCII-Wert '0' fest codieren (yuck) schreiben. –

-3

Können Sie eine Beispieleingabe bereitstellen?

Ich denke, diese Macht Arbeit:

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

Wenn das versuchen fehlschlägt:

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

Die! ist ein Schnitt, stoppt es die Vereinigung. Sie können darüber in Büchern/Tutorials lesen.

+0

Einige Beispiel Eingabe könnte Ausdruck (E, "2 * 14 + 3", "") sein. Der von Ihnen angegebene Code führt zu einer Fehlermeldung, die besagt, dass Nummer/3 eine nicht definierte Prozedur ist und nur die Nummer/1 bekannt ist. Ich dachte an eine DGC-Klausel, um mein Problem zu lösen, aber ich konnte nicht funktionieren. – ubuntudroid

+0

'Zahl/1' ist ein gewöhnliches Prädikat, kein DCG-Prädikat. Außerdem schlägt es fehl, wenn sein Eingang nicht geerdet ist (ist eine Variable). –

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

Aber Sie verwenden eine Syntax, die ich nicht kenne (siehe mein Kommentar oben).