Saya tahu pertanyaan ini berumur 4+ tahun tetapi saya merasa saya harus menambahkan jawaban yang lebih terperinci.
Abstrak Sintaksis Pohon dibuat tidak berbeda dari pohon lain; pernyataan yang lebih benar dalam hal ini adalah bahwa node Sintaks Pohon memiliki jumlah node variadic SEPERTI YANG DIPERLUKAN.
Contohnya adalah ekspresi biner seperti Ekspresi 1 + 2
sederhana seperti itu akan membuat simpul akar tunggal memegang simpul kanan dan kiri yang menyimpan data tentang angka-angka. Dalam bahasa C, itu akan terlihat seperti
struct ASTNode;
union SyntaxNode {
int64_t llVal;
uint64_t ullVal;
struct {
struct ASTNode *left, *right;
} BinaryExpr;
};
enum SyntaxNodeType {
AST_IntVal, AST_Add, AST_Sub, AST_Mul, AST_Div, AST_Mod,
};
struct ASTNode {
union SyntaxNode *Data;
enum SyntaxNodeType Type;
};
Pertanyaan Anda juga bagaimana cara melintasi? Traversing dalam hal ini disebut Visiting Nodes . Mengunjungi setiap Node mengharuskan Anda menggunakan setiap jenis simpul untuk menentukan cara mengevaluasi data masing-masing simpul Sintaks.
Berikut ini contoh lain dari itu di C di mana saya cukup mencetak konten dari setiap node:
void AST_PrintNode(const ASTNode *node)
{
if( !node )
return;
char *opername = NULL;
switch( node->Type ) {
case AST_IntVal:
printf("AST Integer Literal - %lli\n", node->Data->llVal);
break;
case AST_Add:
if( !opername )
opername = "+";
case AST_Sub:
if( !opername )
opername = "-";
case AST_Mul:
if( !opername )
opername = "*";
case AST_Div:
if( !opername )
opername = "/";
case AST_Mod:
if( !opername )
opername = "%";
printf("AST Binary Expr - Oper: \'%s\' Left:\'%p\' | Right:\'%p\'\n", opername, node->Data->BinaryExpr.left, node->Data->BinaryExpr.right);
AST_PrintNode(node->Data->BinaryExpr.left); // NOTE: Recursively Visit each node.
AST_PrintNode(node->Data->BinaryExpr.right);
break;
}
}
Perhatikan bagaimana fungsi secara rekursif mengunjungi setiap node sesuai dengan jenis node yang kita hadapi.
Mari kita tambahkan contoh yang lebih kompleks, if
konstruksi pernyataan! Ingatlah bahwa jika pernyataan juga dapat memiliki klausa opsional lain. Mari kita tambahkan pernyataan if-else ke struktur simpul asli kami. Ingat bahwa jika pernyataan itu sendiri dapat memiliki pernyataan if, maka semacam rekursi dalam sistem simpul kita dapat terjadi. Pernyataan lain bersifat opsional sehingga elsestmt
bidang dapat NULL yang dapat diabaikan oleh fungsi pengunjung rekursif.
struct ASTNode;
union SyntaxNode {
int64_t llVal;
uint64_t ullVal;
struct {
struct ASTNode *left, *right;
} BinaryExpr;
struct {
struct ASTNode *expr, *stmt, *elsestmt;
} IfStmt;
};
enum SyntaxNodeType {
AST_IntVal, AST_Add, AST_Sub, AST_Mul, AST_Div, AST_Mod, AST_IfStmt, AST_ElseStmt, AST_Stmt
};
struct ASTNode {
union SyntaxNode *Data;
enum SyntaxNodeType Type;
};
kembali di fungsi cetak pengunjung simpul kami disebut AST_PrintNode
, kami dapat mengakomodasi if
pernyataan AST membangun dengan menambahkan kode C ini:
case AST_IfStmt:
puts("AST If Statement\n");
AST_PrintNode(node->Data->IfStmt.expr);
AST_PrintNode(node->Data->IfStmt.stmt);
AST_PrintNode(node->Data->IfStmt.elsestmt);
break;
Sesimpel itu! Sebagai kesimpulan, Sintaksis Pohon tidak lebih dari sebatang pohon dari gabungan tagged pohon dan datanya sendiri!