Example #1
0
static int parser_condition(symbItem **src1,symbItem **src2,string &oprname)//传进lable1
{
	if(!parser_expression())
	{
		string testset[]={"","<","<=",">",">=","=","<>"};
		parser_test(testset,7);
		if(lex_sym=="")
		{
			global_error("relational operators","nothing");
			return 0;
		}
	}
	else
	{
		*src1=operand_stack.top();
		operand_stack.pop();
	}
	oprname=lex_sym;
	if(!if_ralation_opr(oprname))
	{
		global_error("relational operators","nothing");
		return 0;
	}
	lex_getsym();
	if(!parser_expression())
		return 0;
	*src2=operand_stack.top();
	operand_stack.pop();
	#ifdef PARSER_DEBUG
	cout << "条件" << endl;
	#endif
	return 1;
}
Example #2
0
int add_column(screen_t* const s, char* header, char* format, char* desc,
               char* expr)
{
  int col_width, err=0;
  int n = s->num_columns;

  expression* e = parser_expression(expr);

  if (e == NULL || e->type == ERROR) {
    free_expression(e);
    error_printf("Invalid expression in column '%s', screen '%s': column ignored\n",
                 header, s->name);
    return -1;
  }

  check_counters_used(e, s, &err);
  if( err > 0 ) {
    free_expression(e);
    return -1;
  }

  if (n == s->num_alloc_columns) {
    s->columns = realloc(s->columns, sizeof(column_t) * (n + alloc_chunk));
    s->num_alloc_columns += alloc_chunk;
  }
  init_column(&s->columns[n]);
  s->columns[n].expression = e;
  s->columns[n].header = strdup(header);
  s->columns[n].format = strdup(format);

  col_width = strlen(header);
  /* setup an empty field with proper width */
  s->columns[n].empty_field = malloc(col_width + 1);
  memset(s->columns[n].empty_field, ' ', col_width - 1);
  s->columns[n].empty_field[col_width - 1] = '-';
  s->columns[n].empty_field[col_width] = '\0';

  /* setup an error field with proper width */
  s->columns[n].error_field = malloc(col_width + 1);
  memset(s->columns[n].error_field, ' ', col_width - 1);
  s->columns[n].error_field[col_width - 1] = '?';
  s->columns[n].error_field[col_width] = '\0';

  if (desc)
    s->columns[n].description = strdup(desc);
  else
    s->columns[n].description = strdup("(unknown)");

  s->num_columns++;
  return n;
}
Example #3
0
/* Adding a new counter in counters list */
int add_counter(screen_t* const s, char* alias, char* config, char* type)
{
  uint64_t int_conf = 0;
  uint32_t int_type = 0;
  int err=0;
  int n;
  expression* expr = NULL;

  if (s->num_counters >=  MAX_EVENTS) {
    error_printf("Too many counters (max %d) in screen '%s', ignoring '%s'\n"
                 "(change MAX_EVENTS and recompile)\n",
                 MAX_EVENTS, s->name, alias);
    return -1;
  }

  int_type = get_counter_type(type, &err);

  if (err > 0) {
    /* error*/
    error_printf("Bad type '%s': ignoring counter '%s'\n", type, alias);
    return -1;
  }

  /* Parse the configuration */
  expr = parser_expression(config);

  err=0;
  int_conf = evaluate_counter_expression(expr, &err);

  free_expression(expr);

  if (err > 0) {
    /* error*/
    error_printf("Bad config '%s': ignoring counter '%s'\n", config, alias);
    return -1;
  }

  n = s->num_counters;
  /* check max available hw counter */
  if (n == s->num_alloc_counters) {
    s->counters = realloc(s->counters, sizeof(counter_t) * (n + alloc_chunk));
    s->num_alloc_counters += alloc_chunk;
  }
  /* initialisation */
  s->counters[n].used = 0;
  s->counters[n].type = int_type;
  s->counters[n].config = int_conf;
  s->counters[n].alias = strdup(alias);
  s->num_counters++;
  return n;
}
Example #4
0
static int parser_statement(symbItem *forbid)
{
	symbItem *tmp;
	if(lex_sym=="ident")
	{
		tmp=symbtable_check(lex_token);
		if(tmp==NULL)
		{
			global_error("legal ident",lex_token);
			return 0;
		}
		if(tmp==forbid)//该标识符不可以被赋值
		{
			global_error("this ident\""+tmp->name+"\"can not be changed.");
			return 0;
		}
		if(tmp->kind=="const")
		{
			global_error(tmp->name+" can not be changed.");
			return 0;
		}
		else if(tmp->kind=="var"||tmp->kind=="parameter")
		{
			lex_getsym();
			if(lex_sym==":="||lex_sym=="=")
			{
				if(lex_sym=="=")
					global_error(":=","=");
			}
			else
			{
				global_error(":=",lex_sym);
				return 0;
			}
			lex_getsym();
			if(!parser_expression())
			{
				return 0;
			}
			symbItem *expre=operand_stack.top();
			operand_stack.pop();
			if(expre->kind=="const")
				expre=parser_create_new_const(expre);
			if(tmp->type=="char"&&expre->type=="integer")
			{
				global_error("integer can not be asssigned to a char");
			//	mark_i=0;
			}
				global_new_quadruple("assign",expre,NULL,tmp);
		}
		else if(tmp->kind=="array")
		{//tmp [src1]
			symbItem *src2;
			lex_getsym();
			if(lex_sym!="[")
			{
				global_error("[",lex_sym);
				return 0;
			}
			lex_getsym();
			if(!parser_expression())
			{
				string testset[]={"","]",":="};
				parser_test(testset,3);
				if(lex_sym=="")
				{
					global_error("]","nothing");
					return 0;
				}
			}
			else
			{
				src2=operand_stack.top();
				operand_stack.pop();
				if(src2->kind=="const")
					src2=parser_create_new_const(src2);
			}
			if(lex_sym!="]")
			{
                global_error("]",lex_sym);
                return 0;
			}
			lex_getsym();
			if(lex_sym==":="||lex_sym=="=")
            {
                if(lex_sym=="=")
                    global_error(":=",lex_sym);
            }
            else
            {
                global_error(":=",lex_sym);
                return 0;
            }
            lex_getsym();
            if(!parser_expression())
                return 0;
            symbItem *ans=operand_stack.top();
            operand_stack.pop();
			if(ans->kind=="const")
				ans=parser_create_new_const(ans);
			if(tmp->type=="char"&&ans->type=="integer")
			{
				global_error("integer can not be asssigned to a char");
			}
            global_new_quadruple("sarray",tmp,src2,ans);//tmp[src2]=ans
		}
		else if(tmp->kind=="function")//函数标示符=表达式
        {//函数标识符只能是本层函数或者他的父层函数
			if(!symbtable_if_can_change_func(tmp->name))
			{
				global_error("function \""+tmp->name+"\" can not be changed in this scope.");
				return 0;
			}
			lex_getsym();
			if(lex_sym!="="&&lex_sym!=":=")
			{
				global_error(":=",lex_sym);
				return 0;
			}
			if(lex_sym=="=")
				global_error(":=",lex_sym);
			lex_getsym();
			if(!parser_expression())
				return 0;
			symbItem *src1=operand_stack.top();
			operand_stack.pop();
			if(src1&&src1->kind=="const")
				src1=parser_create_new_const(src1);
			if(src1->type=="integer"&&tmp->type=="char")
				global_error("integer can not be assigined to a char ");
			global_new_quadruple("assign",src1,NULL,tmp);
        }
        else if(tmp->kind=="procedure")//过程调用语句,tmp已经经过差表
        {
			if(!tmp->size)
			{
				lex_getsym();
				if(lex_sym=="(")
				{
					global_error("no parameter",lex_sym);
					return 0;
				}
			}
			else
			{
				lex_getsym();
				if(!parser_realparameterlist(tmp))
					return 0;
			}
			global_new_quadruple("call",tmp,NULL,NULL);
        }
        else
        {
			global_error("no possible.");
            return 0;
        }
	}
	else if(lex_sym=="if")//
    {
		symbItem *lable1,*lable2,*src1,*src2;
		string oprname;
		lable1=parser_create_new_lable();
        lex_getsym();
        if(!parser_condition(&src1,&src2,oprname))
		{
			string testset[]={"","then","else"};
			parser_test(testset,3);
			if(lex_sym=="")
			{
				global_error("then","nothing");
				return 0;
			}
		}
		else
		{
			oprname=global_anti_ralation[oprname];
			if(src1&&src1->kind=="const")
				src1=parser_create_new_const(src1);
			if(src2&&src2->kind=="const")
				src2=parser_create_new_const(src2);
			global_new_quadruple(oprname,src1,src2,lable1);
		}
		if(lex_sym!="then")
		{
			global_error("then",lex_sym);//容忍缺then的行为
		}
		else
			lex_getsym();
		if(!parser_statement(NULL))
		{
			return 0;//????
		}
		if(lex_sym!="else")
		{
			global_new_quadruple("lab",lable1,NULL,NULL);
		}
		else
		{
			lable2=parser_create_new_lable();
			global_new_quadruple("jmp",lable2,NULL,NULL);
			global_new_quadruple("lab",lable1,NULL,NULL);
			lex_getsym();
			if(!parser_statement(NULL))
				return 0;
			global_new_quadruple("lab",lable2,NULL,NULL);
		}
    }
	else if(lex_sym=="begin")
	{
		lex_getsym();
		if(!parser_compoundstatement())
			return 0;
	}
	else if(lex_sym=="do")
	{
		symbItem *lable1=parser_create_new_lable();
		symbItem *src1,*src2;
		string oprname;
		global_new_quadruple("lab",lable1,NULL,NULL);
		lex_getsym();
		if(!parser_statement(NULL))
		{
			string testset[]={"","while"};
			parser_test(testset,2);
			if(lex_sym=="")
			{
				global_error("while","nothing");
				return 0;
			}
		}
		if(lex_sym!="while")
		{
			global_error("while",lex_sym);
			return 0;
		}
		lex_getsym();
		if(!parser_condition(&src1,&src2,oprname))
			return 0;
		oprname=global_ralation[oprname];
		if(src1&&src1->kind=="const")
			src1=parser_create_new_const(src1);	
		if(src2&&src2->kind=="const")
			src2=parser_create_new_const(src2);
		global_new_quadruple(oprname,src1,src2,lable1);
	}
	else if(lex_sym=="write")
	{
		string testset[]={"",")"};
		lex_getsym();
		if(lex_sym!="(")
		{
			global_error("(",lex_sym);
			string testset2[]={"",")"};
			parser_test(testset2,2);
			if(lex_sym=="")
			{
				global_error(")","nothing");
				return 0;
			}
		}
		else
			lex_getsym();
		if(lex_sym=="string")
		{
			symbItem *item=new symbItem();
			item->name=lex_token;	
			my_write_string.push(lex_token);
			item->value=my_writes_num++;
			item->kind="constpool";
			item->type="string";//digit,char,string,lable
			item->link=NULL;
			global_const_pool.push(item);
			global_new_quadruple("writes",item,NULL,NULL);
			lex_getsym();
			if(lex_sym==",")
			{
				lex_getsym();
				if(!parser_expression())
				{
					parser_test(testset,2);
					if(lex_sym=="")
					{
						global_error(")","nothing");
						return 0;
					}
				}
				else
				{
					symbItem *src=operand_stack.top();
					if(src->kind=="const")
						src=parser_create_new_const(src);
					global_new_quadruple("writee",src,NULL,NULL);
					operand_stack.pop();
				}

			}

		}
		else//表达式
		{
			if(!parser_expression())
			{
				parser_test(testset,2);
				if(lex_sym=="")
				{
					global_error(")","nothing");
					return 0;
				}
			}
			else
			{
				symbItem *src=operand_stack.top();
				if(src->kind=="const")
					src=parser_create_new_const(src);
				global_new_quadruple("writee",src,NULL,NULL);
				operand_stack.pop();
			}

		}
		if(lex_sym!=")")
		{
			global_error(")",lex_sym);
			return 0;
		}
		lex_getsym();
	}
	else if(lex_sym=="read")//func,var,para?
	{
		lex_getsym();
		int flag=0;
		if(lex_sym!="(")
		{
			global_error("(",lex_sym);
			return 0;
		}
		do{
			lex_getsym();
			if(lex_sym!="ident")
			{
				global_error("ident",lex_sym);
				flag=1;
			}
			else//"ident"
			{
				symbItem *ans=symbtable_check(lex_token);
				if(ans==NULL)
				{
					global_error(lex_token+" is not declared in this scope.");
					flag=1;
				}
				else
				{
					if(ans->kind=="const")
					{
						global_error("const \""+ans->name+"\" can not be changed");
						flag=1;
					}
					else if(ans->kind=="procedure")
					{
						global_error("procedure \""+ans->name+"\" can not be changed");
						flag=1;
					}
					else if(ans->kind=="function"&&!symbtable_if_can_change_func(ans->name))
					{
							global_error("function \""+ans->name+"\" can not be changed in this scope.");
							flag=1;
					}
					else
					{
						global_new_quadruple("read",ans,NULL,NULL);
					}
				}
			}
			if(flag)
			{
				string testset[]={"",",",")"};
				parser_test(testset,3);
				if(lex_sym=="")
				{
					global_error(")",lex_sym);
					return 0;
				}
			}
			else
				lex_getsym();
		}while(lex_sym==",");
		if(lex_sym!=")")
		{
			global_error(")",lex_sym);
			return 0;
		}
		lex_getsym();
	}
	else if(lex_sym=="for")
	{
		int downto=0;
		symbItem *tmp,*target,*lable1,*lable2;
		lex_getsym();
		if(lex_sym!="ident")
		{
			global_error("ident",lex_sym);
			return 0;
		}
		tmp=symbtable_check(lex_token);
		int flag=0;
		if(tmp->kind=="const")
		{
			global_error("const \""+tmp->name+"\" can not be changed.");
			flag=1;
		}
		else if(tmp->kind=="procedure")
		{
			global_error("procedure \""+tmp->name+"\" can not be changed.");
			flag=1;
		}
		else
		{
			if(!parser_statement(NULL))
				flag=1;//生成首次赋值语句。
		}
		if(flag)
		{
			string testset[]={"","to","downto"};
			parser_test(testset,3);
			if(lex_sym=="")
			{
				global_error("downto or to","nothing");
				return 0;
			}
		}
		if(lex_sym!="downto"&&lex_sym!="to")
		{
			global_error("downto or to",lex_sym);
			return 0;
		}
		else
			downto=lex_sym=="downto";
		lex_getsym();
		if(!parser_expression())
		{
			string testset[]={"","do"};
			parser_test(testset,2);
			if(lex_sym=="")
			{
				global_error("do","nothing");
				return 0;
			}
		}
		else
		{
			target=operand_stack.top();
			operand_stack.pop();
			if(target->kind=="const")
				target=parser_create_new_const(target);
		}
		if(lex_sym!="do")
		{
			global_error("do",lex_sym);
		//	return 0;
		}
		lex_getsym();
		lable1=parser_create_new_lable();
		lable2=parser_create_new_lable();
		global_new_quadruple("lab",lable1,NULL,NULL);
		string opr=downto?"jl":"jg";
		global_new_quadruple(opr,tmp,target,lable2);
		if(!parser_statement(tmp))
			return 0;
		opr=downto?"dec":"inc";
		global_new_quadruple(opr,tmp,NULL,NULL);
		global_new_quadruple("jmp",lable1,NULL,NULL);
		global_new_quadruple("lab",lable2,NULL,NULL);
	}
	else
	{
		//空语句怎么处理,那就不处理好了?
	}
	#ifdef PARSER_DEBUG
	cout <<"语句"<< endl; 
	#endif
	return 1;
}
Example #5
0
static int parser_factor()
{
	symbItem *operand;
	if(lex_sym=="ident")
	{
		operand=symbtable_check(lex_token);
		if(operand==NULL)
		{
			global_error("legal ident",lex_token);
			return 0;
		}
		if(operand->kind=="array")
		{
			parser_create_new_var(operand);
			symbItem *ans=symbtable_now->last_item,*src2;
			lex_getsym();
			if(lex_sym!="[")
			{
				global_error("[",lex_sym);
				return 0;
			}
			lex_getsym();
			if(!parser_expression())
			{
				string testset[]={"","]"};
				parser_test(testset,2);
				if(lex_sym=="")
				{
					global_error("]","nothing");
					return 0;
				}
			}
			else{
				src2=operand_stack.top();
				operand_stack.pop();
				if(src2->kind=="const")
					src2=parser_create_new_const(src2);
			}
			if(lex_sym!="]")
			{
				global_error("]",lex_sym);
				return 0;
			}
			if(ans->type=="char"&&operand->type=="integer")
			{
				global_error("integer can not be asssigned to a char");
			}
			global_new_quadruple("larray",operand,src2,ans);//ans=operand[src2]
			operand_stack.push(ans);
			lex_getsym();
		}
		else if(operand->kind=="function")
		{
			parser_create_new_var(operand->type);
			symbItem *ans=symbtable_now->last_item;
			lex_getsym();
			if(lex_sym=="("&&!operand->size)
			{
				global_error("no parameter",lex_sym);
				return 0;
			}
			else if(operand->size)
			{
				if(!parser_realparameterlist(operand))
					return 0;
			}
			global_new_quadruple("call",operand,NULL,NULL);
			global_new_quadruple("assign",operand,NULL,ans);
			operand_stack.push(ans);
		}
		else if(operand->kind=="procedure")
		{
			global_error("factor","procedure "+operand->name);
			return 0;
		}
		else
		{
			operand_stack.push(operand);//获得操作数
			lex_getsym();
		}
	}
	else if(lex_sym=="(")
	{
		lex_getsym();
		if(!parser_expression())
		{
			string testset[]={"",")"};
			parser_test(testset,2);
			if(lex_sym=="")
			{
				global_error(")","nothing");
				return 0;
			}
		}
		if(lex_sym!=")")
		{
			global_error(")",lex_sym);
			return 0;
		}
		lex_getsym();
	}
	else if(lex_sym=="digit")
	{
		symbItem *item=new symbItem();
		item->name=numtostring(lex_value);
		item->value=lex_value;
		item->kind="constpool";
		item->type="integer";//digit,char,string,lable
		item->link=NULL;
		operand_stack.push(item);
		global_const_pool.push(item);//放到常量池里面
		lex_getsym();
	}
	else
	{
		global_error("legal factor",lex_sym);
		return 0;
	}
	#ifdef PARSER_DEBUG
	cout << "因子" << endl;
	#endif
	return 1;
}
Example #6
0
//Require: item is func or proc
//暂时不跳读,因为,一行而已。。本身久错了
static int parser_realparameterlist(symbItem *func_proc)
{//func后面一定要紧跟着参数信息,这是四元式中操作数的一部分,虽然你没用到他的值,但你用到的是他的其他信息;
	//need to find the location of func or proc
	stack<symbItem*> para_stack;
	symbItem *src;
	if(lex_sym!="(")
	{
		global_error("(",lex_sym);
		return 0;
	}
	do{
		lex_getsym();
		if(!parser_expression())
		{
			string testset[]={"",",",")"};
			parser_test(testset,3);
			if(lex_sym=="")
			{
				global_error(")","nothing");
				return 0;
			}
		}
		else
		{
			para_stack.push(operand_stack.top());
			operand_stack.pop();
		}
	}while(lex_sym==",");
	if((unsigned)func_proc->size!=para_stack.size())
	{
		global_error("wrong num of parametes in \""+func_proc->name+"\"call.");
		return 0;
	}//good,我是指针我怕谁

	//require: enough para item in the global_table
	int j=func_proc->size;
	symbItem *k=func_proc->link;
	if(func_proc->name==symbtable_now->name)//调用自身此时符号表没调整。
		k=symbtable_now->first_item;
	else if(j&&(k==NULL||k->kind!="parameter"))//这里子表没有撤回的情况有很多,不过一旦动用了这条分支,意味着死循环
	{
		symbTable *tmp=symbtable_now;
		while(tmp->name!=func_proc->name)
			tmp=tmp->father;
		k=tmp->first_item;
	}
	int mark_i=0;
	stack<symbItem*> paras;
	symbItem *twx=k;
	for(int i=1;i<=j;i++)
	{
		paras.push(twx);
		twx=twx->link;
	}
	for(int i=1;i<=j;i++)//k是顺着来的而栈里的参数是反着来的。。
	{
		src=para_stack.top();
		para_stack.pop();
		if(paras.top()->type=="char"&&src->type=="integer")
		{
			global_error("parameter type error:char","integer:");	
			mark_i=1;
		}
		if(paras.top()->para_ifvar&&paras.top()->type=="integer"&&src->type=="char")
		{
			global_error("real parameter type error,integer","char");
		}
		paras.pop();
		if(k->para_ifvar&&src->kind!="const")//可能撤表了也可能没撤
		{
			if(src->kind=="var"&&src->name[0]=='_')
			{
				global_error("legal var parameter","expression");
				mark_i=1;
			}		
			else
				global_new_quadruple("rpara",src,func_proc,NULL);
		}
		else if(k->para_ifvar&&src->kind=="const")
		{
			global_error("legal var parameter","const");
			mark_i=1;
		}
		else
		{
			if(src->kind=="const")
				src=parser_create_new_const(src);
			global_new_quadruple("fpara",src,func_proc,NULL);
		}
			if(k==NULL)
			cout << "are you kidding me!" <<endl;
		k=k->link;//Require k<>NULL;
	}
	if(lex_sym!=")")
	{
		global_error(")",lex_sym);
		return 0;
	}
	lex_getsym();
	#ifdef PARSER_DEBUG
	cout << "实在参数表" << endl;
	#endif
/*	if(mark_i)
		return 0;*/
	return 1;
}