2017-11-07 4 views
3

Ich lege einen Lexer/Parser für eine einfache Programmiersprache mit einem Prolog DCG, die die Liste der Token/Syntax-Struktur mit DCG-Argumente, z.Get Prolog DCG Argumente generiert aus Satz wird geparst

symbol(semicolon) --> ";". 
symbol(if) --> "if". 

und dann wird der Syntaxbaum mit diesen Argumenten zu den DCG-Regeln erstellt.

Allerdings habe ich eine Beule darin, dass, wenn es zu Parsing Variablen und Zahlen (nur ganze Zahlen in dieser Sprache), ich brauche die DCG Argumente zu dynamischen, z.

symbol(number(X)) --> X, {integer(N)}. 

Im Wesentlichen muss ich das DCG-Argument im Wesentlichen aus dem generiert werden, was es tatsächlich analysiert. Gibt es eine Möglichkeit, dies zu tun? Wenn nicht, was könnte ein guter Workaround sein?

EDIT: Als konkretes Beispiel habe ich die Regel bekommt

symbol(num(N)) --> {number_codes(N,C)}, C. 

und ich brauche die Ausgabe N=7 bei der Abfrage phrase(symbol(num(N)),"7").

+1

Es ist definitiv möglich; Hast du [dcg/basics] (http://www.swi-prolog.org/pldoc/doc/_SWI_/library/dcg/basics.pl) gesehen? (Auch der Quellcode dafür [ist ziemlich lehrreich] (http://www.swi-prolog.org/pldoc/doc/_SWI_/library/dcg/basics.pl?show=src#integer/3).) –

+1

Sie sind in der Nähe. 'Symbol (Zahl (X)) -> [X], {Ganzzahl (X)}.' Obwohl Sie vorsichtig sein wollen, da 'Zahl/1' ein Standard-Prolog-Prädikat ist. Vielleicht wähle etwas anderes. – lurker

+0

Ich bin mir aber nicht so sicher; Das spezifische Beispiel, dem ich momentan gegenüberstehe, ist: 'Symbol (num (N)) -> {Zahl_Codes (N, C)}, C'. Ich brauche im Wesentlichen den Ausgang 'N = 7' bei der Eingabe von' Phrase (Symbol (num (N)), "7"). – user2396812

Antwort

2

Ich sehe drei Probleme hier.

  1. phrase/2 möchte auf Listen von Codes arbeiten. Seit Version 7 verfügt SWI über einen systemeigenen Zeichenfolgetyp, der keine DCGs unterstützt. So müssen Sie jetzt auf diese etwas unbequem Formulierung zurückgreifen:

    atom_codes("if", Codes), phrase(symbol(X), Codes) 
    
  2. In der Regel wollen Sie etwas von dem Eingang und dann Hand es bis zu einem gewissen reinen Prolog Prädikat abzulösen, etwas zu tun. Mit anderen Worten, so etwas wie diese:

    symbol(num(N)) --> [C], { number_codes(N, [C]) }. 
    
    ?- atom_codes(9, X), phrase(symbol(S), X). 
    X = [57], 
    S = num(9). 
    

    Dies wird natürlich nur funktionieren, für einstellige Zahlen, die wahrscheinlich nicht das, was Sie wollen, so ...

  3. sollten Sie wahrscheinlich verwenden Sie den Code aus dcg/basics.pl wie folgt aus:

    :- use_module(library(dcg/basics)). 
    
    symbol(num(N)) --> integer(N). 
    
    ?- atom_codes(973, X), phrase(symbol(S), X). 
    X = [57, 55, 51], 
    S = num(973). 
    

    Oder Sie könnten ein copy/paste Sache mit the source code tun. Sie werden wahrscheinlich feststellen, dass alle darin enthaltenen DCG-Regeln entweder mit einem Aufruf einer anderen DCG-Regel beginnen oder sie einen Teil der Eingabe konsumieren und dann etwas anderes tun; Wahrscheinlich willst du nichts generieren und dann in der Eingabe danach suchen.

Verwandte Themen