预处理器:
/** scmppre.c
====================================================================
This is the base source file for pre-compiler
====================================================================
*/
#include "scmppre.h"
static int report_pre_error(char *msg, int code){
printf("Error : %s\nCode : %d\n", msg, code);
return 0;
}
#define CHECK_INDEX( index ) \
if( index >= MAX_SRC_LINE ){\
report_pre_error("Too long line.", index);\
return 0;\
}
/*=======================================================
The main function of pre-compiler.
return 1 : success
0 : fail
========================================================*/
int pre_compiler(FILE * fpInput, FILE * fpOutput){
char str_line_buffer[MAX_SRC_LINE + 1];
int index = 0;
char current_char;
current_char = fgetc(fpInput);
while( current_char != EOF ){
/*========================================================
search the '//' . if exists, jump the rest of the line.
========================================================*/
if( '/' == current_char ){
current_char = fgetc(fpInput);
if( '/' == current_char ){
while( current_char != EOF ){
current_char = fgetc(fpInput);
if( '\n' == current_char ){
/* end of a line */
str_line_buffer[index] = '\n';
index++;
CHECK_INDEX( index )
break;/* stop loop */
}
}
/* output a line */
str_line_buffer[index] = '\0';
fputs(str_line_buffer, fpOutput);
index = 0;
} else{
/* a single '/', just store it and its following byte */
str_line_buffer[index] = '/';
index++;
CHECK_INDEX( index )
if( EOF == current_char ){ /* end of file */
str_line_buffer[index] = '\0';
fputs(str_line_buffer, fpOutput);
index = 0;
return 1;
} else if( '\n' == current_char ){
str_line_buffer[index] = current_char;
index++;
CHECK_INDEX( index )
str_line_buffer[index] = '\0';
fputs(str_line_buffer, fpOutput);
index = 0;
} else{
str_line_buffer[index] = current_char;
index++;
CHECK_INDEX( index )
}
}
} else if( '\n' == current_char ){
str_line_buffer[index] = current_char;
index++;
CHECK_INDEX( index )
str_line_buffer[index] = '\0';
fputs(str_line_buffer, fpOutput);
index = 0;
} else{
str_line_buffer[index] = current_char;
index++;
CHECK_INDEX( index )
}
current_char = fgetc(fpInput);
}
str_line_buffer[index] = '\0';
fputs(str_line_buffer, fpOutput);
index = 0;
return 1;
}
语法分析器
/** scmpstx.c
====================================================================
This is the base source file for Syntax Analyze
====================================================================
*/
#include "scmpstx.h"
int DEFINITION(FileField *fileField, int left_brother_ID, int father_ID);
int VAR_DEF(FileField *fileField, int left_brother_ID, int father_ID);
int FUNC_DEF(FileField *fileField, int left_brother_ID, int father_ID);
int IDENTIFY(FileField *fileField, int left_brother_ID, int father_ID);
int BODY(FileField *fileField, int left_brother_ID, int father_ID);
int VAR_DEFINITION(FileField *fileField, int left_brother_ID, int father_ID);
int STATEMENT_LIST(FileField *fileField, int left_brother_ID, int father_ID);
int ASSIGN_STMT(FileField *fileField, int left_brother_ID, int father_ID);
int IF_STMT(FileField *fileField, int left_brother_ID, int father_ID);
int FOR_STMT(FileField *fileField, int left_brother_ID, int father_ID);
int WHILE_STMT(FileField *fileField, int left_brother_ID, int father_ID);
int FORMULA(FileField *fileField, int left_brother_ID, int father_ID);
int BOOL_FORMULA(FileField *fileField, int left_brother_ID, int father_ID);
int FORMULA_FOLLOW(FileField *fileField, int left_brother_ID, int father_ID);
int BOOL_FORMULA_FOLLOW(FileField *fileField, int left_brother_ID, int father_ID);
int FUNC_CALL(FileField *fileField, int left_brother_ID, int father_ID);
void report_syntax_error(char *func_name, char *detail, int line_number){
printf("Syntax error accured in function '%s()', at line '%d'.\nDetail: %s\n", func_name, line_number, detail);
return;
}
void report_memery_error(char *func_name, int line_number){
printf("Memery error accured in function '%s()', at line '%d'.\n", func_name, line_number);
return;
}
void report_internal_error(char *func_name, int line_number){
printf("Internal error accured in function '%s()', at line '%d'.\n", func_name, line_number);
return;
}
int initialize_IdTable(){
int i=0;
int j=0;
g_IdTable.n_id_num = 0;
g_IdTable.pIdList = (IdentId_P)malloc( ( MAX_SYN_NODE_NUM + 1 ) * sizeof(IdentId) );
if( NULL == g_IdTable.pIdList ){
report_memery_error("initialize_IdTable", __LINE__);
return 0;
}
for( i = 0; i < 51; i++ ){
for( j = 0; j < 61; j++ ){
g_IdTable.two_level_index[i][j] = INVALID_ID;
}
}
return 1;
}
int initialize_SynTree(){
g_SynTree.n_node_num = 0;
g_SynTree.pSynNodeList = (SynNode_P)malloc( ( MAX_SYN_NODE_NUM + 1 ) * sizeof(SynNode) );
if( NULL == g_SynTree.pSynNodeList ){
report_memery_error("initialize_SynTree", __LINE__);
return 0;
}
return 1;
}
int release_IdTable(){
MY_HELP_FREE( g_IdTable.pIdList )
g_IdTable.n_id_num = 0;
return 1;
}
int release_SynTree(){
MY_HELP_FREE( g_SynTree.pSynNodeList );
g_SynTree.n_node_num = 0;
return 1;
}
int syntax_analyzer(FileField *fileField){
int ret = 0;
char * func_name="syntax_analyzer";
/** [ 1 ] initialize a node for whole program **/
g_SynTree.n_node_num = 1;
g_SynTree.pSynNodeList[0].n_father_id = INVALID_ID;
g_SynTree.pSynNodeList[0].n_identifier_id = INVALID_ID;
g_SynTree.pSynNodeList[0].n_left_brother_id = INVALID_ID;
g_SynTree.pSynNodeList[0].n_mode = SYN_NODE_HEAD;
g_SynTree.pSynNodeList[0].n_right_brother_id = INVALID_ID;
g_SynTree.pSynNodeList[0].n_son_id = INVALID_ID;
/** [ 2 ] deal with DEFINITION **/
ret = DEFINITION( fileField, INVALID_ID, 0 );
/** [ 3 ] deal with 'main' **/
if( 0 == ret ){
printf("Syntax_analyzer exit with syntax error.\n");
return 0;
} else{
/* some definition finished, the node 'DEFINITION' is the left brother of 'main' */
g_SynTree.n_node_num++;
CHECK_NODE_NUM( func_name, fileField, g_SynTree.n_node_num )
g_SynTree.pSynNodeList[g_SynTree.n_node_num-1].n_father_id = 0;/* the index of 'main' is g_SynTree.n_node_num-1 */
g_SynTree.pSynNodeList[g_SynTree.n_node_num-1].n_identifier_id = INVALID_ID;
g_SynTree.pSynNodeList[g_SynTree.n_node_num-1].n_left_brother_id = 1;/* the node 'DEFINITION' */
g_SynTree.pSynNodeList[g_SynTree.n_node_num-1].n_mode = SYN_NODE_MAINFUNID;
g_SynTree.pSynNodeList[g_SynTree.n_node_num-1].n_right_brother_id = INVALID_ID;
g_SynTree.pSynNodeList[g_SynTree.n_node_num-1].n_son_id = INVALID_ID;
g_SynTree.pSynNodeList[1].n_right_brother_id = g_SynTree.n_node_num-1;/* fix the right brother for node 'DEFINITION' */
}
/** [ 4 ] deal with '(' and ')' **/
/* [ 4.1 ] jump the spaces after 'main' */
JUMP_SPACES( fileField )
/* [ 4.2 ] check '(' */
if( '(' != fileField->current_ch ){
report_syntax_error( "syntax_analyzer", "missing '('.", fileField->n_current_line );
printf("Syntax_analyzer exit with syntax error.\n");
return 0;
}
/* [ 4.3 ] jump the spaces after '(' */
GET_NEW_CHAR_JUMP_SPACE( fileField )
/* [ 4.4 ] check ')' */
if( ')' != fileField->current_ch ){
report_syntax_error( "syntax_analyzer", "missing ')'.", fileField->n_current_line );
printf("Syntax_analyzer exit with syntax error.\n");
return 0;
}
/* [ 4.5 ] jump the spaces after ')' */
GET_NEW_CHAR_JUMP_SPACE( fileField )
/* [ 4.6 ] check '{' */
if( '{' != fileField->current_ch ){
report_syntax_error( "syntax_analyzer", "missing '{'.", fileField->n_current_line );
printf("Syntax_analyzer exit with syntax error.\n");
return 0;
}
/** [ 5 ] deal with 'BODY' **/
ret = BODY( fileField, g_SynTree.n_node_num-1, 0 );
if( 0 == ret ){
printf("Syntax_analyzer exit with syntax error.\n");
return 0;
}
/* [ 6 ] jump the spaces after 'BODY' */
JUMP_SPACES( fileField )
/* [ 7 ] check '}' */
if( '}' != fileField->current_ch ){
report_syntax_error( "syntax_analyzer", "missing '}'.", fileField->n_current_line );
printf("Syntax_analyzer exit with syntax error.\n");
return 0;
}
/* [ 8 ] jump the spaces after '}' */
GET_NEW_CHAR_JUMP_SPACE( fileField )
if( EOF != fileField->current_ch ){
report_syntax_error( "syntax_analyzer", "Unexpected character.", fileField->n_current_line );
printf("Syntax_analyzer exit with syntax error.\n");
return 0;
}
return 1;
}
int DEFINITION(FileField *fileField, int left_brother_ID, int father_ID){
int ret = 0;
int id_length = 0;
char *func_name="DEFINITION";
unsigned int tempIndex = 0;
/* [ 1 ] make a node for 'DEFINITION' */
tempIndex = g_SynTree.n_node_num;
g_SynTree.pSynNodeList[ tempIndex ].n_father_id = father_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_identifier_id = INVALID_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_left_brother_id = left_brother_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_mode = SYN_NODE_DEFINITION;
g_SynTree.pSynNodeList[ tempIndex ].n_right_brother_id = INVALID_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_son_id = INVALID_ID;
/* [ 2 ] fix for father and left brother */
FIX_FATHER_LBROTHER( father_ID, left_brother_ID, tempIndex )
g_SynTree.n_node_num++;
CHECK_NODE_NUM( func_name, fileField, g_SynTree.n_node_num )
/* [ 3 ] deal with VAR_DEF */
ret = VAR_DEF( fileField, INVALID_ID, tempIndex );
if( 0 == ret ){
return 0;
}
if( 1000 == ret ){
report_syntax_error( func_name, "Invalid identifier .", fileField->n_current_line );
return 0;
} else if( 100 == ret ){
return 1;
} else if( 200 == ret ){
/* [ 4 ] deal with FUNC_DEF */
ret = FUNC_DEF( fileField, INVALID_ID, tempIndex );
if( 0 == ret ){
return 0;
}
} else if( 300 == ret ){
report_syntax_error( "syntax_analyzer", "Unexpected character.", fileField->n_current_line );
return 0;
}
/* [ 5 ] deal with DEFINITION recursively */
ret = DEFINITION( fileField, g_SynTree.pSynNodeList[ tempIndex ].n_son_id, tempIndex );
if( 0 == ret ){
return 0;
}
return 1;
}
/** if it returns 1000, it's unkown character, maybe '}' **/
/** if it returns 100, an identifier name 'main' is stored in FileField.name_buf **/
/** if it returns 200, an identifier name ( not 'main' ) is stored in FileField.name_buf **/
/** if it returns 300, it's 'if' 'while' 'for' **/
int VAR_DEF(FileField *fileField, int left_brother_ID, int father_ID){
int ret = 0;
char *func_name="VAR_DEF";
unsigned int tempIndex = 0;
unsigned int ident_index = 0;
int id_length = 0;
/* [ 1 ] jump spaces in the head */
GET_NEW_CHAR_JUMP_SPACE( fileField )
/* [ 2 ] get the first token */
GET_IDENTIFY( fileField, fileField->name_buf, id_length )
if( 0 == id_length ){
return 1000;
}
CHECK_KEY_WORD( fileField->name_buf, ret )
if( KEY_WORD_MAIN == ret ){
/* no definition */
return 100;
} else if( KEY_WORD_NO == ret ){
/* it's an identifier. maybe statment_list or syntax error. */
return 200;
}else if( KEY_WORD_INT == ret ){
/* [ 3 ] deal with 'VAR_DEF' */
/* [ 3.1 ] make a node for 'VAR_DEF' */
tempIndex = g_SynTree.n_node_num;
g_SynTree.pSynNodeList[ tempIndex ].n_father_id = father_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_identifier_id = INVALID_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_left_brother_id = left_brother_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_mode = SYN_NODE_VAR_DEF;
g_SynTree.pSynNodeList[ tempIndex ].n_right_brother_id = INVALID_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_son_id = INVALID_ID;
/* [ 3.2 ] fix for father and left brother */
FIX_FATHER_LBROTHER( father_ID, left_brother_ID, tempIndex )
g_SynTree.n_node_num++;
CHECK_NODE_NUM( func_name, fileField, g_SynTree.n_node_num )
/* [ 3.3 ] get the identifier after 'int' */
GET_IDENTIFY( fileField, fileField->name_buf, id_length )
if( 0 == id_length ){
report_syntax_error( func_name, "Invalid identifier .", fileField->n_current_line );
return 0;
}
CHECK_KEY_WORD( fileField->name_buf, ret )
if( KEY_WORD_NO != ret ){
/* Invalid identifier */
report_syntax_error( func_name, "Invalid identifier: key-word.", fileField->n_current_line );
return 0;
}
/* [ 3.4 ] use a IdentId to store the identifier and make a syntax node */
ret = add_to_IdTable(fileField, fileField->name_buf, id_length, SYN_NODE_VARID, &ident_index);
if( 0 == ret ){
return 0;
}
g_SynTree.pSynNodeList[ g_SynTree.n_node_num ].n_father_id = tempIndex;
g_SynTree.pSynNodeList[ g_SynTree.n_node_num ].n_identifier_id = ident_index;
g_SynTree.pSynNodeList[ g_SynTree.n_node_num ].n_left_brother_id = INVALID_ID;
g_SynTree.pSynNodeList[ g_SynTree.n_node_num ].n_mode = SYN_NODE_VARID;
g_SynTree.pSynNodeList[ g_SynTree.n_node_num ].n_right_brother_id = INVALID_ID;
g_SynTree.pSynNodeList[ g_SynTree.n_node_num ].n_son_id = INVALID_ID;
/* [ 3.5 ] fix for father and left brother */
FIX_FATHER_LBROTHER( tempIndex, INVALID_ID, g_SynTree.n_node_num )
g_SynTree.n_node_num++;
CHECK_NODE_NUM( func_name, fileField, g_SynTree.n_node_num )
/* [ 3.6 ] deal with ';' */
JUMP_SPACES( fileField )
if( ';' != fileField->current_ch ){
report_syntax_error( func_name, "Missing ';' .", fileField->n_current_line );
return 0;
}
return 1;
} else{
/* it's 'if' 'while' 'for' */
return 300;
}
}
int FUNC_DEF(FileField *fileField, int left_brother_ID, int father_ID){
int ret = 0;
char *func_name="FUNC_DEF";
unsigned int tempIndex = 0;
unsigned int ident_index = 0;
int id_length = 0;
/* [ 1 ] deal with FUNC_DEF */
/* [ 1.1 ] make a node for FUNC_DEF */
g_SynTree.pSynNodeList[ g_SynTree.n_node_num ].n_father_id = father_ID;
g_SynTree.pSynNodeList[ g_SynTree.n_node_num ].n_identifier_id = INVALID_ID;
g_SynTree.pSynNodeList[ g_SynTree.n_node_num ].n_left_brother_id = left_brother_ID;
g_SynTree.pSynNodeList[ g_SynTree.n_node_num ].n_mode = SYN_NODE_FUNC_DEF;
g_SynTree.pSynNodeList[ g_SynTree.n_node_num ].n_right_brother_id = INVALID_ID;
g_SynTree.pSynNodeList[ g_SynTree.n_node_num ].n_son_id = INVALID_ID;
/* [ 1.2 ] fix for father and left brother */
FIX_FATHER_LBROTHER( father_ID, left_brother_ID, g_SynTree.n_node_num )
g_SynTree.n_node_num++;
CHECK_NODE_NUM( func_name, fileField, g_SynTree.n_node_num )
/* [ 1.3 ] use a IdentId to store the identifier and make a syntax node */
ret = add_to_IdTable(fileField, fileField->name_buf, (int)strlen( fileField->name_buf ), SYN_NODE_FUNID, &ident_index);
if( 0 == ret ){
return 0;
}
g_SynTree.pSynNodeList[ g_SynTree.n_node_num ].n_father_id = g_SynTree.n_node_num - 1;
g_SynTree.pSynNodeList[ g_SynTree.n_node_num ].n_identifier_id = ident_index;
g_SynTree.pSynNodeList[ g_SynTree.n_node_num ].n_left_brother_id = INVALID_ID;
g_SynTree.pSynNodeList[ g_SynTree.n_node_num ].n_mode = SYN_NODE_FUNID;
g_SynTree.pSynNodeList[ g_SynTree.n_node_num ].n_right_brother_id = INVALID_ID;
g_SynTree.pSynNodeList[ g_SynTree.n_node_num ].n_son_id = INVALID_ID;
/* [ 1.4 ] fix for father and left brother */
FIX_FATHER_LBROTHER( g_SynTree.n_node_num - 1, INVALID_ID, g_SynTree.n_node_num )
g_SynTree.n_node_num++;
CHECK_NODE_NUM( func_name, fileField, g_SynTree.n_node_num )
/* [ 1.5 ] deal with '(' */
JUMP_SPACES( fileField )
if( '(' != fileField->current_ch ){
report_syntax_error( func_name, "Missing '(' .", fileField->n_current_line );
return 0;
}
/* [ 1.6 ] deal with ')' */
GET_NEW_CHAR_JUMP_SPACE( fileField )
if( ')' != fileField->current_ch ){
report_syntax_error( func_name, "Missing ')' .", fileField->n_current_line );
return 0;
}
/* [ 1.7 ] deal with '{' */
GET_NEW_CHAR_JUMP_SPACE( fileField )
if( '{' != fileField->current_ch ){
report_syntax_error( func_name, "Missing '{' .", fileField->n_current_line );
return 0;
}
/* [ 1.8 ] deal with 'BODY' */
ret = BODY( fileField, g_SynTree.n_node_num - 1, g_SynTree.n_node_num - 2 );
if( 0 == ret ){
return 0;
}
/* [ 1.9 ] deal with '}' */
JUMP_SPACES( fileField )
if( '}' != fileField->current_ch ){
report_syntax_error( func_name, "Missing '}' .", fileField->n_current_line );
return 0;
}
return 1;
}
int BODY(FileField *fileField, int left_brother_ID, int father_ID){
int ret = 0;
char *func_name="BODY";
unsigned int tempIndex = 0;
int id_length = 0;
/* [ 1 ] make a node for 'BODY' */
tempIndex = g_SynTree.n_node_num;
g_SynTree.pSynNodeList[ tempIndex ].n_father_id = father_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_identifier_id = INVALID_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_left_brother_id = left_brother_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_mode = SYN_NODE_BODY;
g_SynTree.pSynNodeList[ tempIndex ].n_right_brother_id = INVALID_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_son_id = INVALID_ID;
/* [ 2 ] fix for father and left brother */
FIX_FATHER_LBROTHER( father_ID, left_brother_ID, tempIndex )
g_SynTree.n_node_num++;
CHECK_NODE_NUM( func_name, fileField, g_SynTree.n_node_num )
/* [ 3 ] deal with VAR_DEFINITION */
ret = VAR_DEFINITION( fileField, INVALID_ID, tempIndex );
if( 0 == ret ){
return 0;
}
if( 400 != ret ){
/* [ 4 ] deal with STATEMENT_LIST */
ret = STATEMENT_LIST( fileField, g_SynTree.pSynNodeList[ tempIndex ].n_son_id, tempIndex );
if( 0 == ret ){
return 0;
}
}
return 1;
}
/** if it returns 200, an identifier name is stored in FileField.name_buf **/
/** if it returns 300, it's 'if' 'while' 'for' **/
/** if it returns 400, an empty statment_list is following **/
int VAR_DEFINITION(FileField *fileField, int left_brother_ID, int father_ID){
int ret = 0;
char *func_name="VAR_DEFINITION";
unsigned int tempIndex = 0;
/* [ 1 ] make a node for 'VAR_DEFINITION' */
tempIndex = g_SynTree.n_node_num;
g_SynTree.pSynNodeList[ tempIndex ].n_father_id = father_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_identifier_id = INVALID_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_left_brother_id = left_brother_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_mode = SYN_NODE_VAR_DEFINITION;
g_SynTree.pSynNodeList[ tempIndex ].n_right_brother_id = INVALID_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_son_id = INVALID_ID;
/* [ 2 ] fix for father and left brother */
FIX_FATHER_LBROTHER( father_ID, left_brother_ID, tempIndex )
g_SynTree.n_node_num++;
CHECK_NODE_NUM( func_name, fileField, g_SynTree.n_node_num )
/* [ 3 ] deal with VAR_DEF */
ret = VAR_DEF( fileField, INVALID_ID, tempIndex );
if( 0 == ret ){
return 0;
}
if( 1000 == ret ){
if( '}' != fileField->current_ch ){
report_syntax_error( func_name, "Invalid identifier .", fileField->n_current_line );
return 0;
} else{
/* Empty statement_list */
return 400;
}
} else if( 100 == ret ){
report_syntax_error( "syntax_analyzer", "Unexpected key-word 'main'.", fileField->n_current_line );
return 0;/* 'main' can't be here */
} else if( 200 == ret ){
/* [ 4 ] 'STATEMENT_LIST' is following */
return 200;
} else if( 300 == ret ){
/* [ 5 ] 'STATEMENT_LIST' is following */
return 300;
}
ret = VAR_DEFINITION( fileField, g_SynTree.pSynNodeList[ tempIndex ].n_son_id, tempIndex );
return ret;
}
int STATEMENT_LIST(FileField *fileField, int left_brother_ID, int father_ID){
int ret = 0;
char *func_name="STATEMENT_LIST";
unsigned int tempIndex = 0;
unsigned int id_length = 0;
/* [ 1 ] make a node for 'STATEMENT_LIST' */
tempIndex = g_SynTree.n_node_num;
g_SynTree.pSynNodeList[ tempIndex ].n_father_id = father_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_identifier_id = INVALID_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_left_brother_id = left_brother_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_mode = SYN_NODE_STATEMENT_LIST;
g_SynTree.pSynNodeList[ tempIndex ].n_right_brother_id = INVALID_ID;
g_SynTree.pSynNodeList[ tempIndex ].n_son_id = INVALID_ID;
/* [ 2 ] fix for father and left brother */
FIX_FATHER_LBROTHER( father_ID, left_brother_ID, tempIndex )
g_SynTree.n_node_num++;
CHECK_NODE_NUM( func_name, fileField, g_SynTree.n_node_num )
/* [ 3 ] check the last byte */
if( '}' == fileField->current_ch ){
/* the statement list is empty */
return 1;
}
/* [ 4 ] check the key-word which has already been read */
CHECK_KEY_WORD( fileField->name_buf, ret )
if( KEY_WORD_NO == ret ){
JUMP_SPACES( fileField )
if( '=' == fileField->current_ch ){
/* [ 4.1 ] it's an ASSIGN_STMT */
ret = ASSIGN_STMT( fileField, INVALID_ID, tempIndex );
if( 0 == ret ){
return 0;
}
JUMP_SPACES( fileField )
if( ';' != fileField->current_ch ){
/* check ';' */
report_syntax_error( func_name, "Missing ';' .", fileField->n_current_line );
return 0;
}
} else if( '(' == fileField->current_ch ){
/* [ 4.2 ] it's an FUNC_CALL */
ret = FUNC_CALL( fileField, INVALID_ID, tempIndex );
if( 0 == ret ){
return 0;
}
} else{
report_syntax_error( func_name, "Unknown statement .", fileField->n_current_line );
return 0;
}
} else if( KEY_WORD_IF == ret ){
/* [ 4.2 ] deal with IF_STMT */
ret = IF_STMT( fileField, INVALID_ID, tempIndex );
if( 0 == ret ){
return 0;
}
} else if( KEY_WORD_WHILE == ret ){
/* [ 4.3 ] deal with WHILE_STMT */
ret = WHILE_STMT( fileField, INVALID_ID, tempIndex );
if( 0 == ret ){
return 0;
}
} else if( KEY_WORD_FOR == ret ){
/* [ 4.4 ] deal with FOR_STMT */
ret = FOR_STMT( fileField, INVALID_ID, tempIndex );
if( 0 == ret