⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 varproc.cpp

📁 一个小型C语言编译器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <assert.h>

#include "token.h"
#include "string.h"
//#include "self_def.h"
#include "datatypedef.h"
#include "input.h"
#include "debug.h"


void vardefproc(void);
void ouputvardef(void);
void _vardefproc(void);

void VarInsert(VAR_USE_REC var_use_rec);


VAR_LVL_RECORD  GlobalVarRec = {0, NULL, NULL, NULL};
VAR_LVL_RECORD* CurVarRec = & GlobalVarRec;
VAR_LVL_RECORD* ParentVarRec = CurVarRec->parent;

extern char*          token; 




void levelstart();//处理'{'字符
void levelend();//处理'}'字符


int Define_proc();
static int Define_check_state1();
static int Define_check_state2();
static int Define_check_state3();
static int Define_check_state4();
static int Define_check_state5();
static int Define_check_state6();
static int Define_check_state7();
static int Define_check_state8();
static int Define_check_state9();
static int Define_check_state10();
static int Define_check_state11();
static int Define_check_Fun1();
static int Define_check_Fun2();
static int Define_check_finish();

int Expr_proc(int tok);
static int Expr_check_start(int tok);
static int Expr_check_finish();
static int Expr_check_state1();
static int Expr_check_state2();
static int Expr_check_state3();
static int Expr_check_state4();


int While_proc();
static int While_check_state1();
static int While_check_state2();

int If_proc();
static int If_check_state1();
static int If_check_state2();

int For_proc();
static int For_check_state1();
static int For_check_state2();
static int For_check_state3();
static int For_check_state4();

int Clause_proc();
static int Clause_Start();
static int Clause_check_state1();
static int Clause_check_state2();
static int Clause_check_state3();
static int Clause_check_state4();
static int Clause_check_state5();
static int Clause_check_state6();
static int Clause_check_state7();
static int Clause_check_state8();
static int Clause_check_finish();

void vardefproc()
{
    int l_token = 0;
    VARDEFNODE temp  = {NULL, NULL};

    while(9) {
        l_token = gettok();

        if(l_token == EOI) {
            return ;
        }

        if(l_token >= 1 && l_token <= 7) { //变量定义,声明
            printf("[file:%s][line:%d] var define\r\n", __FILE__, __LINE__);
            Define_proc();
        } else if (l_token == '{') {
            levelstart();
        } else if (l_token == '}') {
            //levelend();
        } else if (l_token == IF){
            If_proc();
        } else if (l_token == WHILE) {
            While_proc();
        } else if (l_token == FOR) {
            For_proc();
        } else if (l_token == ID) {
            Clause_proc();
        } else {
            
        }

    }
}






VAR_LIST_NODE* _find(char* name, VAR_LIST_NODE* start)
{
    if(start == NULL) 
        return NULL;

    while(start) {
        if( !strcmp (name, start->varname) ){//变量名称相同,认为是同一个变量
            return start;
        }
        start = start->next;
    }

    return NULL;
}



VAR_LIST_NODE* find(char* name)
{
    VAR_LVL_RECORD* curvarrec = CurVarRec;
    VAR_LIST_NODE*  result = NULL;

    assert(name);       //确保传入变量名称不为空
    

    while(curvarrec){
        result = _find(name, curvarrec->varlist);
        if(result)
            return result;
        else 
            curvarrec = curvarrec->parent;
    }

    return NULL;
}

void VarInsert(VAR_USE_REC var_use_rec)
{
    VAR_LIST_NODE* current = NULL;
    VAR_LIST_NODE* var_node = NULL;

    assert(CurVarRec);              //确保当前变量记录不能为空
    current = CurVarRec->varlist;

     trace("inset the var into the varlist\n");


     //查找当前变量使用记录中是否有相关变量的记录
     if(var_use_rec.use_type == DEFINE_STATE){
        var_node = _find(var_use_rec.name, CurVarRec->varlist);
     } else { //if (var_use_rec.use_type == USE_STATE){
        var_node = find(var_use_rec.name);
     }

     if(var_node) {//该变量以前有定义
         VAR_USE_STATE* temp = var_node->usestate;
         VAR_USE_STATE* use_state = NULL;
            
         trace("var has been defined\n");

         use_state = (VAR_USE_STATE*) malloc(sizeof(VAR_USE_STATE));
         if(use_state == NULL) {
             printf("mem alloc fail!");
             exit(0);
         }

         trace("the mem: 0x%p\n", use_state);

         use_state->line = var_use_rec.line;
         use_state->use_type = var_use_rec.use_type;
         use_state->next = NULL;

         if(temp == NULL) {//该变量未曾定义或使用过
             var_node->usestate = use_state;
             return;
         } else {//该变量已经有使用定义记录
             while(temp->next){
                 temp = temp->next;
             }
             temp->next = use_state;
         }
     } else {//该变量以前已经被定义了
         VAR_LIST_NODE* temp  = NULL;
         VAR_USE_STATE* stemp = NULL;

         temp = (VAR_LIST_NODE*) malloc(sizeof (VAR_LIST_NODE));
         if(temp == NULL) {
             printf("mem alloc fail!");
             exit(0);
         }

         stemp = (VAR_USE_STATE*) malloc(sizeof(VAR_USE_STATE));
         if(stemp == NULL){
             printf("mem alloc fail!");
             exit(0);                        //使用EXIT退出程序,暂时不考虑内存释放
         }

         stemp->line = var_use_rec.line ;
         stemp->use_type = var_use_rec.use_type ;
         stemp->next = NULL;

         temp->varname = var_use_rec.name;
         temp->next    = CurVarRec->varlist;
         temp->usestate = stemp;
            
         CurVarRec->varlist = temp;
         return ;
     }
}


void dispvaruse(VAR_LIST_NODE* curr)
{
    VAR_USE_STATE* usestate = NULL;

    assert (curr);

    usestate = (curr->usestate);
    while(usestate) {
        printf("        [useline]: %d        [usetype]: ", usestate->line);
        if (usestate->use_type == ASS_STATE) {
            printf("use\n");
        } else if (usestate->use_type == REF_STATE){
            printf("reference\n");
        } else {
            printf("define\n");
        }
        usestate = usestate->next;
    }
}
void dispvar(VAR_LVL_RECORD* curr)
{
    VAR_LIST_NODE* varnode;

    assert(curr);

    varnode = curr->varlist;
    while(varnode) {
        printf("%s\n", varnode->varname);
        dispvaruse(varnode);
        varnode = varnode->next ;
    }
}

void ouputvardef(void)
{
    VAR_LVL_RECORD* temp = &GlobalVarRec;

    int level = 0;
    while(temp) {
        printf("---------------------------------------------------------\n");
        printf("++++++++++++ level %3d ++++++++++++++++++++++++++++++++++\n", level);
        printf("---------------------------------------------------------\n");
        ++level;
        dispvar(temp);
        temp = temp->child;
    }
    
}


#define     UNDEFINED       0
#define     DEFINED         1
#define     UNDEF_USE       2
#define     DEF_USE         3
#define     REDEFINED       4


#define     NO_ERR                  0
#define     ERR_USE_BUT_NO_DEF      1
#define     ERR_DEF_BUT_NO_USE      2
#define     ERR_REDEF               3   

void varcheck(VAR_LIST_NODE* var)
{
    VAR_USE_STATE *varuse   = NULL;
    int varusestate         = UNDEFINED;
    int varrecno            = 0;
    int errorcode           = NO_ERR;

    varuse = var->usestate;
    
    while(varuse) {
        switch(varuse->use_type) {
            case DEFINE_STATE:  //当前变量是定义状态
                if (varusestate == UNDEFINED) {
                    varusestate = DEFINED;
                    errorcode = NO_ERR;
                } else if (varusestate == DEFINED || varusestate == DEF_USE || varusestate == REDEFINED) {
                    varusestate = REDEFINED;
                    errorcode = ERR_REDEF;
                } else if (varusestate == UNDEF_USE) {
                    varusestate = DEFINED;
                    errorcode = NO_ERR;
                } else {
                    printf("var use state is wrong\n");
                }
                break;
            
            case REF_STATE:
            case ASS_STATE:
            case USE_STATE:     //当前变量是使用状态
                if (varusestate == DEFINED || varusestate == REDEFINED || varusestate == DEF_USE) {
                    varusestate = DEF_USE;
                    errorcode = NO_ERR;
                } else if (varusestate == UNDEFINED || varusestate == UNDEF_USE){
                    varusestate = UNDEF_USE;
                    errorcode = ERR_USE_BUT_NO_DEF;
                } else {
                    printf("var use state is wrong\n");
                }
                break;

            default:
                break;
        }

        if (varusestate == DEFINED && varuse->next == NULL) {
            errorcode = ERR_DEF_BUT_NO_USE;
        }

        //输出错误

        varuse = varuse->next;
    }
}




void varlistfree(VAR_LIST_NODE* list)
{
    //释放变量表申请的资源
}

int level_count = 0;
void levelstart()//处理'{'字符
{
    VAR_LVL_RECORD *temp = NULL;

    temp = (VAR_LVL_RECORD*)malloc(sizeof (VAR_LVL_RECORD));
    if(temp == NULL) {
        printf("mem alloc fail!\n");
        exit(0);
    }
    memset(temp, 0, sizeof (VAR_LVL_RECORD));

    temp->parent = CurVarRec;
    CurVarRec->child = temp;
    CurVarRec = temp;

    ++level_count;
    printf("[line:%d]the { scaned\n", lineno);
}

void levelend()//处理'}'字符
{
    //当遇到'}'字符时,需要扫描变量表,获取错误信息
    VAR_LIST_NODE* curvar;

    curvar = CurVarRec->varlist;
    while(curvar) {//对每个变量的使用进行检测
        varcheck(curvar);
        curvar = curvar->next;
    }
    
    //释放变量使用记录表的资源
    varlistfree(CurVarRec->varlist);

    //释放当前层的记录块
    CurVarRec = CurVarRec->parent;
    free(CurVarRec->child);
    CurVarRec->child = NULL;
}



int istype(int tok) 
{
    if (tok>= FLOAT && tok <= UNSIGNED) {
        return 1;
    } else {
        return 0;
    }
}


int isnum(int tok) 
{
    if (tok == ICON || tok == FCON || tok == SCON) {
        return 1;
    } else {
        return 0;
    }
}


int isoperator(int tok)
{
    if(tok == '+' || tok == '-' || tok == '*' || tok == '/' ||
       tok == '!' || /*tok == '=' ||*/ 
       tok == '>' || tok == '<' ||
       tok == '&' || tok == '|' || tok == '~' || tok == '^' ||
       (tok >= ANDAND && tok <= LSHIFT)   // &&, ||, <=, ==, !=, >=, >>, <<
       ) {
        return 1;
    } else {
        return 0;
    }
}
/*
if while for 语句中表达式的检测

                        ID/NUM
                   /-----------------\
                   |                 |
                   |                 |
         ID        \/       OP       |
[START]------->[Finish]------------>[S1]
                |    /\
                |    |
               (|    |)       )
                |    |<--------------\
                |    |               |
                \/   |     ID/NUM    |       ,
               [   S2  ]----------->[S3]---------->[S4]
                                     /\             |
                                     |              |
                                     |     ID/NUM   |
                                     \--------------/

可以是ID,ID OP ID,Func(ID,...)
*/

static int line_no;
static char* varname = NULL;




int Expr_proc(int tok)
{
    return Expr_check_start(tok);
}


static int Expr_check_start(int tok)
{
    /*
    int tok = -1;

    tok = gettok();

    if( tok == EOI ) {
        return -5;//END_OF_FILE
    }
    */
    if(tok == ID){
        varname = token;
        line_no = lineno; 
        if(varname == NULL) {
            printf("[%s][%d]:error id\\n", __FILE__, __LINE__);
            exit(1);
        }
        return Expr_check_finish();
    } else {
        printf("[%s][%d]:wrong express\n", __FILE__, __LINE__);
        printf("wrong lineno = %d, tok = %d",lineno, tok);
        return -1;
    }

}

static int Expr_check_state1()
{
    int tok = -1;

    tok = gettok();
    if(tok == EOI) {
        return -5;
    }

    if (tok == ID) {//当前是变量名称
        varname = token;
        line_no = lineno;
        if (varname == NULL) {
            printf("[%s][%d]:error id\n", __FILE__, __LINE__);
            exit(1);
        }

        //把这个变量加入到变量表中
        {
            VAR_USE_REC temp = {0};

            temp.line = line_no;
            temp.name = varname;
            temp.use_type = REF_STATE;//USE_STATE;

            VarInsert(temp);
        }
        varname = NULL;
        return Expr_check_finish();
    }else if (isnum(tok)){
        return Expr_check_finish();
    } else {
        printf("[%s][%d]: error input\n", __FILE__, __LINE__);
        return -1;
    }

}

static int Expr_check_state2()
{
    int tok = -1;

    tok = gettok();
    if(tok == EOI) {
        return -5;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -