📄 varproc.cpp
字号:
#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 + -