C语言简单子集编译器源码(第一版)

预处理器:
/** 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
  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C语言子集编译器是一种专门用于编译C语言子集的软件工具。C语言子集是指C语言的一个部分,它包含C语言的一些核心语法和特性,但不包括全部的C语言功能。设计C语言子集编译器需要以下几个步骤: 1. 词法分析:首先,编译器需要将输入的源代码文件分成一个个的词法单元,例如标识符、关键字、运算符等。这一步骤将源代码转化为一系列的记号。 2. 语法分析:通过使用语法分析器,编译器可以根据C语言子集的语法规则来解析记号流,从而构建出语法树。语法树反映了源代码的结构和层次关系。 3. 语义分析:在这一步,编译器将进行类型检查和语义分析。它会检查变量的声明和使用是否正确,并进行类型匹配等操作。通过语义分析,编译器可以找出源代码中的错误和不合规范的地方。 4. 代码生成:在这一阶段,编译器将根据语法树生成目标代码。通常,目标代码是一个中间代码,如三地址码或抽象语法树。然后,编译器可以将中间代码转化为目标机器码。 5. 优化:最后,编译器可能会进行一些优化操作,以提高生成的目标代码的执行效率。例如,常量折叠、循环优化和死代码删除等。 通过以上的步骤,设计一个C语言子集编译器可以将C语言子集的源代码转化为机器可执行的目标代码。这个编译器可以为程序员提供方便,帮助他们快速开发和调试C语言子集的程序。同时,通过优化生成的代码,还可以提高程序的执行效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值