나는이 질문이 4 세 이상이라는 것을 알고 있지만 더 자세한 답변을 추가해야한다고 생각합니다.
추상 구문 트리는 다른 트리와 다르게 생성되지 않습니다. 이 경우 구문 트리 노드에는 다양한 노드가 필요합니다.
예를 들어 1 + 2
간단한 표현식과 같은 이진 표현식 은 숫자에 대한 데이터를 보유하는 오른쪽 및 왼쪽 노드를 보유하는 단일 루트 노드를 작성합니다. C 언어에서는 다음과 같이 보입니다.
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;
};
당신의 질문은 또한 횡단하는 방법이었습니다? 이 경우 순회를 방문 노드 라고 합니다 . 각 노드를 방문하려면 각 노드 유형을 사용하여 각 구문 노드의 데이터를 평가하는 방법을 결정해야합니다.
다음은 C에서 각 노드의 내용을 간단히 인쇄하는 또 다른 예입니다.
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;
}
}
처리하는 노드 유형에 따라 함수가 각 노드를 재귀 적으로 방문하는 방법에 주목하십시오.
보다 복잡한 예제, if
구문 구성을 추가합시다 ! if 문은 선택적 else 절을 가질 수 있습니다. if-else 문을 원래 노드 구조에 추가합시다. if 문 자체에도 if 문이있을 수 있으므로 노드 시스템 내에서 일종의 재귀가 발생할 수 있습니다. 다른 명령문은 선택 사항이므로 elsestmt
재귀 방문자 함수가 무시할 수있는 필드는 NULL 일 수 있습니다.
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;
};
라는 노드 방문자 인쇄 함수로 돌아가서 다음 C 코드를 추가하여 AST 구문 문을 AST_PrintNode
수용 할 수 있습니다 if
.
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;
저것과 같이 쉬운! 결론적으로, Syntax Tree는 그 나무와 그 데이터 자체의 결합 된 태그의 나무에 지나지 않습니다!