Wenn Sie dem Vorschlag von @mat folgen und Ihre Syntax für einen Token-Stream verwenden, hier ein einfaches Beispiel.
Angenommen, Sie die folgende BNF Definition Ihrer Sprache haben:
<program> ::= program begin <statement_list> end .
<statement_list> ::= <statement> | <statement> ; <statement_list>
<statement> ::= ...
Sie entscheiden müssen, wie Sie Ihren Parse-Baum darstellen wollen. Ich habe gewählt, was eine klobige Art zu sein scheint, den n-stufigen Syntaxbaum als eingebettete Listen darzustellen (ich habe nicht viel darüber nachgedacht), aber hoffentlich gibt Ihnen das die Idee, wie es funktioniert. Ihre DCG würde die BNF direkt reflektieren, und das Argument wäre der Parsing-Baum:
program([key(program), key(begin), AST_statement_list, key(end), sep(.)]) -->
[key(program), key(begin)],
statement_list(AST_statement),
[key(end), sep(.)].
statement_list([AST]) --> statement(AST).
statement_list([AST_statement | AST_statement_list]) -->
statement(AST_statement),
statement_list(AST_statement_list).
statement(AST) --> ...
Sie telefonisch vom DCG mit dem Token-Stream analysieren würde:
phrase(program(ParseTree), TokenStream).
Ein Programm Parse-Baum aussehen würde, :
[key(program), key(begin), [Statement1_List, Statement2_List, ...], key(end), sep(.)]
Jeder StatementN_List
würde sich ein n-ary Baum für die Anweisung Teilstruktur sein.
Siehe [tag: dcg]. Reine Prolog-Beziehungen können in allen Richtungen * verwendet werden. Das bedeutet, dass Sie, sobald Sie die Beziehung zwischen einer Liste und ihrem Syntaxbaum beschrieben haben, ** und ** beide Listen und Bäume analysieren können. Beginnen Sie mit einer DCG-Regel wie 'Programm (AST) -> ...', die die Beziehung zwischen einem abstrakten Syntaxbaum und einer Liste von Token beschreibt. – mat