Yeonnnnny

신택스 분석기 - (10) 명령문 분석 본문

컴파일러

신택스 분석기 - (10) 명령문 분석

yeonny_do 2024. 11. 10. 02:18

1. 명령문의 종류

 

statement_list_opt
	: /*empty*/  	{$$=makeNode(N_STMT_LIST_NIL, NIL, NIL, NIL);}
	| statement_list {$$=$1;}
	;

statement_list
	: statement             	{$$=makeNode(N_STMT_LIST, $1, NIL, makeNode(N_STMT_LIST_NIL, NIL, NIL, NIL));}
	| statement_list statement  {$$=makeNodeList(N_STMT_LIST, $1, $2);}

statement
	: labeled_statement	{$$=$1;}
	| compound_statement   {$$=$1;}
	| expression_statement {$$=$1;}
	| selection_statement  {$$=$1;}
	| iteration_statement  {$$=$1;}
	| jump_statement   	{$$=$1;}
	;

 

 명령문들은 레이블이 붙여진 명령문, 복합문, 수식문, 선택문, 반복문, 분기문 등을 말하는데, 명령문을 분석하면, <statement>는 여러 가지 명령문을 위한 신택스 트리를 가리킴.

 

 

 

2. 레이블된 명령문(Labeled_statement) 분석

 

// 레이블된 명령문
labeled_statement
	: CASE_SYM constant_expression COLON statement {$$=makeNode(N_STMT_LABEL_CASE, $2, 0, $4);}
	| DEFAULT_SYM COLON statement {$$=makeNode(N_STMT_LABEL_DEFAULT, 0, $3, 0);}
	;

 

  레이블이 앞에 붙여진 명령을 레이블된 명령문이라 하는데, 레이블에는 case 레이블과 default 레이블이 있음. 레이블된 명령문을 분석하여 case 레이블이 나오는 경우에는, 새로운 노드 N_STMT_LABEL_CASE를 만들어 그 좌측 자식으로 <constant_expression>이 가리키는 수식을 위한 신택스 트리, 우측 자식으로는 <statement>가 가리키는 명령문을 위한 신택스 트리를 연결한 신택스 트리를 <labeled_statement>가 가리키도록 함. default 레이블이 나오는 경우, 새로운 노드 N_STMT_LABEL_DEFAULT를 만들어 그 자식으로 <statement>가 가리키는 명령문을 위한 신택스 트리를 연결한 신택스 트리를 <labeled_statement>가 가리키도록 함.

 

 

 

3. 복합문(Compound_statement) 분석

 

// 복합문
compound_statement
	: LR{$$=current_id; current_level++;} declaration_list_opt
  	statement_list_opt RR{checkForwardReference(); $$=makeNode(N_STMT_COMPOUND, $3, NIL, $4); current_id=$2; current_level--;}
    	// 나중에 완전히 선언되는가를 검사
    	// 함수 선언문의 몸체나 복합문의 레벨값 처리
    	//  current_id를 몸체나 복합문의 분석 전 저장했던 값으로 변경
	;

 

  복합문은 중괄호 사이에 선언문들과 명령문들이 나오는 형식임. 선언문에서 선언되는 명칭들은 복합문 안에서만 사용할 수 있으며 (지역 변수의 성격), 복합문 바깥에서는 더 이상 사용할 수 없게 됨. 선언문들에 대한 분석을 하면 <declaration_list>는 복합문 안에서 선언된 명칭들에 대한 심볼 테이블 목록을 가리킴. 이후에 나오는 명령문들에 대한 분석이 끝나면, 명령문 갯수만큼의 N_STMT_LIST노드(없는 경우, N_STMT_LIST_NIL 노드)를 만들어 모든 명령문에 대한 신택스 트리들을 자식으로 차례대로 연결한 신택스 트리를 <statement_list>가 가리킴. 복합문을 분석하면, N_STMT_COMPOUND 이름의 새로운 노드를 만들어 그 좌측 자식으로 <declaration_list>가 가르키는 심볼 테이블 목록을 연결하고 우측 자식으로 <statement_list>가 가리키는 명령문 목록을 위한 신택스 트리를 자식으로 연결하여 이를 <compound_statement>가 가리키도록 함.

 

 

 

4. 수식문 (Expression_statement) 분석

 

// 수식문
expression_statement
	: SEMICOLON        	{$$=makeNode(N_STMT_EMPTY, 0,0,0);}
	| expression SEMICOLON {$$=makeNode(N_STMT_EXPRESSION, 0, $1, 0);}
	;

 

  수식문을 분석하면, 수식이 없이 세미콜론만 있는 경우는 새로운 노드 N_STMT_EMPTY를 만들고, 수식이 있는 경우는 새로운 노드 N_STMT_EXPRESSION을 만들어 <expression>이 가리키는 신택스 트리를 자식으로 하고, 최종적으로 그 노드를 <expression_statement>가 가리키도록 함.

 

 

 

5. 선택문 (Selection_statement) 분석

 

// 선택문
selection_statement
	: IF_SYM LP expression RP statement                	{$$=makeNode(N_STMT_IF, $3, 0, $5);}
	| IF_SYM LP expression RP statement ELSE_SYM statement {$$=makeNode(N_STMT_IF_ELSE, $3, $5, $7);}
	| SWITCH_SYM LP expression RP statement            	{$$=makeNode(N_STMT_SWITCH, $3, 0, $5);}
	;

 

  선택문을 분석하면 <selection_statement>는 다음과 같은 세 종류에 따라 만들어지는 신택스 트리를 가리키게 됨.

  • if문에 else 부분이 없는 경우는 새로운 노드 N_STMT_IF를 만들어 <expression>과 <statement>가 가리키는 신택스 트리를 자식으로 연결함.
  • if문에 else 부분이 있는 경우는 새로운 노드 N_STMT_IF_ELSE를 만들어 <expression>과 첫 번째 <statement> 및 두 번째 <statement>가 가리키는 신택스 트리를 자식으로 연결함.
  • switch문인 경우 새로운 노드 N_STMT_SWITCH를 만들어 <expression>과 <statement>가 가리키는 신택스 트리를 자식으로 연결함. 

 

6. 반복문 (Iteration_statement) 분석

 

// 반복문
iteration_statement
	: WHILE_SYM LP expression RP statement              	{$$=makeNode(N_STMT_WHILE, $3, 0, $5);}
	| DO_SYM statement WHILE_SYM LP expression RP SEMICOLON {$$=makeNode(N_STMT_DO, $2, 0, $5);}
	| FOR_SYM LP for_expression RP statement            	{$$=makeNode(N_STMT_FOR, $3, 0, $5);}
	;

for_expression
	: expression_opt SEMICOLON expression_opt SEMICOLON expression_opt {$$=makeNode(N_FOR_EXP, $1, $3, $5);}
	;

expression_opt
	: /*empty*/  {$$=0;}
	| expression {$$=$1;}
	;

 

  반복문을 분석하면 <iteration_statement>는 다음과 같은 세 종류에 따라 만들어지는 신택스 트리를 가리키게 됨.

  • while문인 경우, 새로운 노드 N_STMT_WHILE을 만들어 <expression>과 <statement>가 가리키는 신택스 트리를 자식으로 연결함.
  • do문인 경우, 새로운 노드 N_STMT_DO를 만들어 <statement> 와 <expression>이 가리키는 신택스 트리를 자식으로 연결함.
  • for문에서 <for_expression> 부분을 분석하면,
    • 새로운 노드 N_FOR_EXP를 만들어 <for_expression>이 가리키도록 함.
    • <for_expression> 안에 나오는 세 개의 <expression_opt>를 가리키는 신택스 트리를 자식으로 연결함.
    • for문을 분석하면 새로운 노드 N_STMT_FOR를 만들어 <for_expression>과 <statement>가 가리키는 신택스 트리를 자식으로 연결함.

 

 

7. 분기문 (Jump_statement) 분석

 

// 분기문
jump_statement
	: RETURN_SYM expression_opt SEMICOLON {$$=makeNode(N_STMT_RETURN, 0,$2,0);}
	| CONTINUE_SYM SEMICOLON          	{$$=makeNode(N_STMT_CONTINUE, 0, 0, 0);
	| BREAK_SYM SEMICOLON             	{$$=makeNode(N_STMT_BREAK, 0, 0, 0);}
//	| GOTO_SYM IDENTIFIER SEMICOLON // goto는 편의상 다루지 않음
	;

 

  분기문을 분석하면 <jump_statement>는 다음과 같은 세 가지 종류에 따라 만들어지는 신택스 트리를 가리키게 됨.

  • return 문인 경우, 새로운 노드 N_STMT_RETURN 을 만들어 <expression_opt>가 가리키는 신택스 트리를 자식으로 연결함.
  • continue 문인 경우에 새로운 노드 N_STMT_CONTINUE 를 만듦.
  • break 문인 경우 새로운 노드 N_STMT_BREAK를 만듦.