Beispiel #1
0
static int parser_vardeclaration()
{
	string testset[]={"",";"};
	do{
		if(!parser_vardefinition())
		{
			parser_test(testset,2);
			if(lex_sym=="")
			{
				global_error(";","nothing");
				return 0;
			}
		}
		if(lex_sym!=";")
		{
			global_error(";","nothing");
		}
		else
			lex_getsym();
	}while(lex_sym=="ident");
	#ifdef PARSER_DEBUG
	cout << "变量声明" << endl;
	#endif
	return 1;
}
Beispiel #2
0
static int parser_formalparalist(int &para_size)
{
	string testset[]={"",";",")"};
	if(lex_sym!="(")
	{
		global_error("(",lex_sym);
		return 0;
	}
	else
	{
		do{
			lex_getsym();
			if(!parser_formalparasection(para_size))
			{
				parser_test(testset,3);
				if(lex_sym=="")
				{
					global_error(")","nothing");
					return 0;
				}
			}
		}while(lex_sym==";");
		if(lex_sym!=")")
		{
			global_error(")",lex_sym);
			return 0;
		}
		lex_getsym();
	}
	#ifdef PARSER_DEBUG
	cout << "形式参数表" << endl;
	#endif
	return 1;
}
Beispiel #3
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;
}
Beispiel #4
0
static int parser_compoundstatement()//require 读了begin 后面的一个单词
{
	string testset[]={"",";","end"};
	if(!parser_statement(NULL))
	{
		parser_test(testset,3);
		if(lex_sym=="")
		{
			global_error("end","nothing");
			return 0;
		}
	}
	while(true)
	{
		if(lex_sym==";")
			lex_getsym();
		else
		{
			string testset[]={"ident","end","","if","for","do","begin","write","read"};
			parser_test(testset,9);
			if(lex_sym=="end")
				break;
			else if(lex_sym=="")
			{
				global_error("end","nothing");
				return 0;
			}
			global_error(";","nothing");
		}
		if(!parser_statement(NULL))
		{
			parser_test(testset,3);
			if(lex_sym=="")
			{
				global_error("end","nothing");
				return 0;
			}
		}
	}
	if(lex_sym!="end")
	{
		global_error("end","nothing");
		return 0;
	}
	lex_getsym();
	#ifdef PARSER_DEBUG
	cout << "复合语句" << endl;
	#endif
	return 1;
}
Beispiel #5
0
void parser_program()
{
	lex_getch();
	lex_getsym();
	string testset[]={".",""};
	if(!parser_procedure())
	{
		parser_test(testset,2);
		if(lex_sym=="")
		{
			global_error(".","nothing");
			return;
		}
	}
	if(lex_sym!=".")
		global_error(".","nothing");
}
Beispiel #6
0
static int if_ralation_opr(string a)
{
	if(a==":=")
	{
		global_error("=",a);
		return 1;
	}
	return a=="="||
		a==">"||a==">="||
		a=="<"||a=="<="||
		a=="<>";
}
   T const& get_global( std::string const& key )
 {
   try
   {
     return boost::any_cast< T const& >( global( key ) );
   }
   catch ( boost::bad_any_cast& )
   {
     throw global_error( key );
   }
   static T t;
   return t;
 }
Beispiel #8
0
static void parser_test(string a[],int num,int &flag)
{
	flag=0;
	while(!parser_ifintestset(a,num,lex_sym))
	{
		lex_getsym();
		if(!flag)
		{
			global_error("Illegal parser in procedure");
			flag=1;
		}
	}
}
Beispiel #9
0
static int parser_constdeclaration()
{
	string testset[]={",",";",""};
	if(!parser_constdefinition())//去找他的合法后继们
	{
		parser_test(testset,3);
		if(lex_sym=="")//找到了终止符号集
		{
			global_error(";","nothing");
			return 0;
		}
	}//读到了合法的后继之后就应该继续往下干。
	while(lex_sym==",")
	{
		lex_getsym();
		if(!parser_constdefinition())
		{
			parser_test(testset,3);
			if(lex_sym=="")
			{
				global_error(";","nothing");
				return 0;
			}
		}
	}

	if(lex_sym!=";")
	{
		global_error(";","nothing");
	//	string testset={"","var","function","procedure"}//找他的合法后继。。
		return 0;
	}
	lex_getsym();
	#ifdef PARSER_DEBUG
	cout << "常量声明" << endl;
	#endif
	return 1;
}
Beispiel #10
0
int	main(int ac, char **av)
{
  char *buff;
  t_nbr	res;

  if (ac != 4)
    {
      my_putstr("usage : ");
      my_putstr(av[0]);
      my_putstr("base ops\"()+-*/%\" exp_len\n");
      return (1);
    }
  check_size(av);
  buff = buffer(av[3]);
  global_error(av, buff);
  trad_base_to_ascii(av, buff);
  my_init_zero(&res);
  eval_expr(buff, &res, my_strlen(av[1]));
  trad_ascii_to_base(av, &res);
  free(res.str);
  free(buff);
  return (0);
}
Beispiel #11
0
static void vm_loop(su_state *s, function_t *func) {
	value_t tmpv, tmpv2;
	instruction_t inst;
	int tmp, narg, i, j, k;
	const char *tmpcs;
	su_debug_data dbg;

	s->frame = FRAME();
	s->prot = func->prot;

	#define ARITH_OP(op) \
		su_check_type(s, -2, SU_NUMBER); \
		su_check_type(s, -1, SU_NUMBER); \
		STK(-2)->obj.num = STK(-2)->obj.num op STK(-1)->obj.num; \
		su_pop(s, 1); \
		break;

	#define LOG_OP(op) \
		su_check_type(s, -2, SU_NUMBER); \
		su_check_type(s, -1, SU_NUMBER); \
		STK(-2)->type = SU_BOOLEAN; \
		STK(-2)->obj.b = STK(-2)->obj.num op STK(-1)->obj.num; \
		su_pop(s, 1); \
		break;

	for (s->pc = 0; s->pc < s->prot->num_inst; s->pc++) {
		tmp = s->interrupt | atomic_get(&s->msi->interrupt);
		if (tmp) {
			if ((tmp & ISCOLLECT) == ISCOLLECT) {
				su_thread_indisposable(s);
				su_thread_disposable(s);
			}
			if ((tmp & IGC) == IGC) {
				unmask_thread_interrupt(s, IGC);
				gc_trace(s);
			}
			if ((tmp & IBREAK) == IBREAK) {
				unmask_thread_interrupt(s, IBREAK);
				dbg.file = s->prot->name->str;
				dbg.line = s->prot->lineinf[s->pc];
				s->debug_cb(s, &dbg, s->debug_cb_data);
			}
		}
		inst = s->prot->inst[s->pc];
		switch (inst.id) {
			case OP_PUSH:
				push_value(s, &func->constants[inst.a]);
				break;
			case OP_POP:
				su_pop(s, inst.a);
				break;
			case OP_ADD: ARITH_OP(+)
			case OP_SUB: ARITH_OP(-)
			case OP_MUL: ARITH_OP(*)
			case OP_DIV:
				su_check_type(s, -2, SU_NUMBER);
				su_check_type(s, -1, SU_NUMBER);
				su_assert(s, STK(-1)->obj.num != 0.0, "Division by zero!");
				STK(-2)->obj.num = STK(-2)->obj.num / STK(-1)->obj.num;
				su_pop(s, 1);
				break;
			case OP_MOD:
				su_check_type(s, -2, SU_NUMBER);
				su_check_type(s, -1, SU_NUMBER);
				STK(-2)->obj.num = (double)((int)STK(-2)->obj.num % (int)STK(-1)->obj.num);
				su_pop(s, 1);
				break;
			case OP_POW:
				su_check_type(s, -2, SU_NUMBER);
				su_check_type(s, -1, SU_NUMBER);
				STK(-2)->obj.num = pow(STK(-2)->obj.num, STK(-1)->obj.num);
				su_pop(s, 1);
				break;
			case OP_UNM:
				su_check_type(s, -1, SU_NUMBER);
				STK(-1)->obj.num = -STK(-1)->obj.num;
				break;
			case OP_EQ:
				STK(-2)->obj.b = value_eq(STK(-2), STK(-1));
				STK(-2)->type = SU_BOOLEAN;
				su_pop(s, 1);
				break;
			case OP_LESS: LOG_OP(<);
			case OP_LEQUAL: LOG_OP(<=);
			case OP_NOT:
				if (STK(-1)->type == SU_BOOLEAN) {
					STK(-1)->obj.b = !STK(-1)->obj.b;
				} else {
					STK(-1)->obj.b = (STK(-1)->type == SU_NIL) ? 1 : 0;
					STK(-1)->type = SU_BOOLEAN;
				}
				break;
			case OP_AND:
				tmp = STK(-2)->type != SU_NIL && (STK(-2)->type != SU_BOOLEAN || STK(-2)->obj.b);
				if (tmp && STK(-1)->type != SU_NIL && (STK(-1)->type != SU_BOOLEAN || STK(-1)->obj.b)) {
					s->stack[s->stack_top - 2] = *STK(-1);
				} else {
					STK(-2)->obj.b = 0;
					STK(-2)->type = SU_BOOLEAN;
				}
				su_pop(s, 1);
				break;
			case OP_OR:
				if (STK(-2)->type != SU_NIL && (STK(-2)->type != SU_BOOLEAN || STK(-2)->obj.b)) {
					/* return -2 */
				} else if (STK(-1)->type != SU_NIL && (STK(-1)->type != SU_BOOLEAN || STK(-1)->obj.b)) {
					s->stack[s->stack_top - 2] = *STK(-1);
				} else {
					STK(-2)->obj.b = 0;
					STK(-2)->type = SU_BOOLEAN;
				}
				su_pop(s, 1);
				break;
			case OP_TEST:
				if (STK(-1)->type != SU_NIL && (STK(-1)->type != SU_BOOLEAN || STK(-1)->obj.b))
					s->pc = inst.b - 1;
				su_pop(s, 1);
				break;
			case OP_FOR:
				if (STK(-2)->type == SU_NIL) {
					su_swap(s, -2, -1);
					s->stack_top--;
					s->pc = inst.b - 1;
				} else {
					s->stack_top--;
					su_check_type(s, -1, SU_SEQ);
					su_rest(s, -1);
					su_swap(s, -2, -1);
					su_first(s, -1);
					su_swap(s, -2, -1);
					s->stack_top--;
				}
				break;
			case OP_JMP:
				s->pc = inst.b - 1;
				break;
			case OP_RETURN:
				s->pc = s->frame->ret_addr - 1;
				s->prot = s->frame->func->prot;
				func = s->frame->func;

				s->stack[s->frame->stack_top] = *STK(-1);
				s->stack_top = s->frame->stack_top + 1;
				s->frame_top--;
				s->frame = FRAME();
				break;
			case OP_TCALL:
				s->pc = s->frame->ret_addr - 1;
				s->prot = s->frame->func->prot;
				func = s->frame->func;

				memmove(&s->stack[s->frame->stack_top], &s->stack[s->stack_top - (inst.a + 1)], sizeof(value_t) * (inst.a + 1));
				s->stack_top = s->frame->stack_top + inst.a + 1;
				s->frame_top--;
				s->frame = FRAME();

				/* Do a normal call. */
			case OP_CALL:
				tmp = s->stack_top - inst.a - 1;
				switch (s->stack[tmp].type) {
					case SU_FUNCTION:
						s->frame = &s->frames[s->frame_top++];
						assert(s->frame_top <= MAX_CALLS);
						s->frame->ret_addr = s->pc + 1;
						s->frame->func = func;
						s->frame->stack_top = tmp;

						func = s->stack[tmp].obj.func;
						if (func->narg < 0)
							su_vector(s, inst.a);
						else if (func->narg != inst.a)
							su_error(s, "Bad number of arguments to function! Expected %i, but got %i.", (int)func->narg, (int)inst.a);

						s->prot = func->prot;
						s->pc = -1;
						break;
					case SU_NATIVEFUNC:
						narg = s->narg;
						s->narg = inst.a;
						if (s->stack[tmp].obj.nfunc(s, inst.a)) {
							s->stack[tmp] = *STK(-1);
						} else {
							s->stack[tmp].type = SU_NIL;
						}
						s->stack_top = tmp + 1;
						s->narg = narg;
						break;
					case SU_VECTOR:
						if (inst.a == 1) {
							su_check_type(s, -1, SU_NUMBER);
							tmpv = vector_index(s, s->stack[tmp].obj.vec, su_tointeger(s, -1));
							su_pop(s, 2);
							push_value(s, &tmpv);
						} else {
							for (i = -inst.a, j = 0; i; i++, j++) {
								su_check_type(s, i - j, SU_NUMBER);
								tmpv = vector_index(s, s->stack[tmp].obj.vec, su_tointeger(s, i - j));
								push_value(s, &tmpv);
							}
							su_vector(s, inst.a);
							s->stack[tmp] = s->stack[s->stack_top - 1];
							s->stack_top -= inst.a + 1;
						}
						break;
					case SU_MAP:
						if (inst.a == 1) {
							tmpv2 = *STK(-1);
							tmpv = map_get(s, s->stack[tmp].obj.m, &tmpv2, hash_value(&tmpv2));
							su_assert(s, tmpv.type != SU_INV, "No value with key: %s", stringify(s, &tmpv2));
							su_pop(s, 2);
							push_value(s, &tmpv);
						} else {
							for (i = -inst.a, j = 0; i; i++, j += 2) {
								tmpv2 = *STK(i - j);
								push_value(s, &tmpv2);
								tmpv = map_get(s, s->stack[tmp].obj.m, &tmpv2, hash_value(&tmpv2));
								su_assert(s, tmpv.type != SU_INV, "No value with key: %s", stringify(s, &tmpv2));
								push_value(s, &tmpv);
							}
							su_map(s, inst.a);
							s->stack[tmp] = s->stack[s->stack_top - 1];
							s->stack_top -= inst.a + 1;
						}
						break;
					case SU_STRING:
						if (inst.a == 1) {
							su_check_type(s, -1, SU_NUMBER);
							j = su_tointeger(s, -1);
							su_assert(s, j < s->stack[tmp].obj.str->size, "Out of range!");
							s->scratch_pad[0] = s->stack[tmp].obj.str->str[j];
							su_pop(s, 2);
							su_pushbytes(s, s->scratch_pad, 1);
						} else {
							k = 0;
							for (i = -inst.a; i; i++) {
								su_check_type(s, i, SU_NUMBER);
								j = su_tointeger(s, i);
								su_assert(s, j < s->stack[tmp].obj.str->size, "Out of range!");
								s->scratch_pad[k++] = s->stack[tmp].obj.str->str[j];
								assert(k < SU_SCRATCHPAD_SIZE);
							}
							su_pushbytes(s, s->scratch_pad, k);
							s->stack[tmp] = s->stack[s->stack_top - 1];
							s->stack_top -= inst.a + 1;
						}
						break;
					case SU_NATIVEDATA:
						tmpv = s->stack[tmp];
						if (tmpv.obj.data->vt && tmpv.obj.data->vt->call) {
							narg = s->narg;
							s->narg = inst.a;
							if (tmpv.obj.data->vt->call(s, (void*)tmpv.obj.data->data, inst.a))
								s->stack[tmp] = *STK(-1);
							else
								s->stack[tmp].type = SU_NIL;
							s->stack_top = tmp + 1;
							s->narg = narg;
							break;
						}
					default:
						if (inst.a == 1 && isseq(s, &s->stack[tmp])) {
							su_check_type(s, -1, SU_STRING);
							tmpcs = su_tostring(s, -1, NULL);
							if (!strcmp(tmpcs, "first")) {
								s->stack[(--s->stack_top) - 1] = seq_first(s, STK(-1)->obj.q);
								break;
							} else if (!strcmp(tmpcs, "rest")) {
								s->stack[(--s->stack_top) - 1] = seq_rest(s, STK(-1)->obj.q);
								break;
							}
						}
						su_error(s, "Can't apply '%s'.", type_name(s->stack[tmp].type));
				}
				break;
			case OP_LAMBDA:
				assert(inst.a < s->prot->num_prot);
				lambda(s, &s->prot->prot[inst.a], inst.b);
				break;
			case OP_GETGLOBAL:
				tmpv = func->constants[inst.a];
				su_assert(s, tmpv.type == SU_STRING, "Global key must be a string!");
				tmpv = map_get(s, unref_local(s, s->stack[SU_GLOBAL_INDEX].obj.loc).obj.m, &tmpv, hash_value(&tmpv));
				if (tmpv.type == SU_INV)
					global_error(s, "Undefined global variable", &func->constants[inst.a]);
				push_value(s, &tmpv);
				break;
			case OP_SETGLOBAL:
				tmpv = func->constants[inst.a];
				su_assert(s, tmpv.type == SU_STRING, "Global key must be a string!");
				i = hash_value(&tmpv);
				tmpv2 = unref_local(s, s->stack[SU_GLOBAL_INDEX].obj.loc);
				tmpv = map_insert(s, tmpv2.obj.m, &tmpv, i, STK(-1));
				set_local(s, s->stack[SU_GLOBAL_INDEX].obj.loc, &tmpv);
				break;
			case OP_SHIFT:
				s->stack[s->stack_top - (inst.a + 1)] = *STK(-1);
				s->stack_top -= inst.a;
				break;
			case OP_LOAD:
				assert(FRAME()->stack_top + inst.a < s->stack_top);
				push_value(s, &s->stack[FRAME()->stack_top + inst.a]);
				break;
			case OP_LUP:
				assert(inst.a < func->num_ups);
				push_value(s, &func->upvalues[inst.a]);
				break;
			case OP_LCL:
				assert(inst.b < s->msi->num_c_lambdas);
				push_value(s, &s->msi->c_lambdas[inst.b]);
				break;
			default:
				assert(0);
		}

		#undef ARITH_OP
		#undef LOG_OP
	}
}
Beispiel #12
0
static int parser_procedure()
{
	if(lex_sym=="const")
	{
		lex_getsym();
		if(!parser_constdeclaration())
		{
			string testset[]={"","var","procedure","function","begin"};
			parser_test(testset,5);
			if(lex_sym=="")
			{
				global_error("begin","nothing");
				return 0;
			}
		}
	}
	{
		string testset[]={"","var","procedure","function","begin"};
		int flag;
		parser_test(testset,5,flag);
		if(lex_sym=="")
		{
			global_error("begin","nothing");
			return 0;
		}
	}
	if(lex_sym=="var")
	{
		lex_getsym();
		if(!parser_vardeclaration())
		{
			string testset[]={"","procedure","function","begin"};
			parser_test(testset,4);
			if(lex_sym=="")
			{
				global_error("begin","nothing");
				return 0;
			}
		}
	}
	{
		int flag;
		string testset[]={"","procedure","function","begin"};
		parser_test(testset,4,flag);
		if(lex_sym=="")
		{
			global_error("begin","nothing");
			return 0;
		}
	}
	while(lex_sym=="function"||lex_sym=="procedure")
	{
		string testset[]={"","procedure","function","begin"};
		int flag=1;
		if(lex_sym=="function")
		{
			lex_getsym();
			flag=parser_functiondeclaration();
		}
		else
		{
			lex_getsym();
			flag=parser_proceduredeclaration();
		}
		if(!flag)
		{
			parser_test(testset,4);
			if(lex_sym=="")
			{
				global_error("begin","nothing");
				return 0;
			}
		}
	}
	{
		int flag;
		string testset[]={"","begin"};
		parser_test(testset,2,flag);
		if(lex_sym=="")
		{
			global_error("begin","nothing");
			return 0;
		}
	}
	if(lex_sym!="begin")
	{
		global_error("begin","nothing");
		return 0;
	}
	lex_getsym();
	symbItem *func;	
	if(symbtable_now->father)
		func=symbtable_now->father->last_item;
	else
	{
		func=new symbItem();
		func->name="main";
		func->kind="constpool";
		func->type="lable";
		func->link=NULL;
		global_const_pool.push(func);
	}
	func->adr=function_adr++;
	global_new_quadruple("func",func,NULL,NULL);
	if(!parser_compoundstatement())
		return 0;
	global_new_quadruple("ret",func,NULL,NULL);
	symbtable_up_level();
	#ifdef PARSER_DEBUG
	cout << "prcedure" << endl;
	#endif
	return 1;
}
Beispiel #13
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;
}
Beispiel #14
0
static int parser_formalparasection(int &para_size)
{
	int paraifvar=0;
	symbItem *start;
	string paratype;
	if(lex_sym=="var")
	{
		paraifvar=1;
		lex_getsym();
	}
	if(lex_sym!="ident")
	{
		global_error("ident",lex_sym);
		return 0;
	}
	else
	{
		para_size++;
		if(!symbtable_enter(lex_token,"parameter","",0,paraifvar))
			return 0;
		start=symbtable_now->last_item;
		lex_getsym();
		while(lex_sym==",")
		{
			lex_getsym();
			if(lex_sym!="ident")
			{
				global_error("ident",lex_sym);
				return 0;
			}
			else
			{
				para_size++;
				if(!symbtable_enter(lex_token,"parameter","",0,paraifvar))
					return 0;
				lex_getsym();
			}
		}
		if(lex_sym!=":")
		{
			global_error(":",lex_sym);
			return 0;
		}
		lex_getsym();
		if(lex_sym!="integer"&&lex_sym!="char")
		{
			global_error("char or integer",lex_sym);
			return 0;
		}
		else
		{
			paratype=lex_sym;
			while(start!=NULL)
			{
				start->type=paratype;
				start=start->link;
			}
			lex_getsym();
		}
	}
	#ifdef PARSER_DEBUG
	cout << "形式参数段" << endl;
	#endif
	return 1;
}
Beispiel #15
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;
}
Beispiel #16
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;
}
Beispiel #17
0
static int parser_proceduredeclaration()
{
	int para_size=0;
	symbTable *start=symbtable_now;
	string procename;
	string testset[]={"",";"};
	if(lex_sym!="ident")
	{
		global_error("ident",lex_sym);
		return 0;
	}
	else
	{
		if(!symbtable_enter(lex_token,"procedure","",0,0))
			return 0;
		symbtable_new_level(lex_token);
		lex_getsym();
		if(lex_sym!=";")
		{
			if(!parser_formalparalist(para_size))
			{
				parser_test(testset,2);
				if(lex_sym=="")
				{
					global_error(";","nothing");
					return 0;
				}
			}
			if(lex_sym!=";")
			{
				global_error(";",lex_sym);
				string testset[]={"","const","var","begin","function","procedure"};
				parser_test(testset,6);
				if(lex_sym=="")
				{
					global_error("procedure\""+lex_token+"\" body expected.");
					return 0;
				}
			}
			else
				lex_getsym();
		}
		else lex_getsym();
		start->last_item->size=para_size;
	}
	if(!parser_procedure())
	{
		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();
	#ifdef PARSER_DEBUG 
    cout << "过程声明" << endl;
	#endif
	return 1;
}
Beispiel #18
0
static int parser_functiondeclaration()
{
	int para_size=0;
	symbTable *start=symbtable_now;
	string testset[]={"",":"};
	string functype;
	if(lex_sym!="ident")
	{
		global_error("ident",lex_sym);
		return 0;
	}
	else
	{
		if(!symbtable_enter(lex_token,"function","",0,0))
			return 0;
		symbtable_new_level(lex_token);
		lex_getsym();
		if(lex_sym!=":")
		{
			if(!parser_formalparalist(para_size))
			{
				parser_test(testset,2);
				if(lex_sym=="")
				{
					global_error(":","nothing");
					return 0;
				}
			}
			if(lex_sym!=":")
			{
				global_error(":","nothing");
				return 0;
			}
		}
		lex_getsym();
		if(lex_sym!="char"&&lex_sym!="integer")
		{
			global_error("char or integer",lex_sym);
			return 0;
		}

		functype=lex_sym;
		lex_getsym();
		start->last_item->size=para_size;//那是上一层的需要反填的东西。
		start->last_item->type=functype;
		if(lex_sym!=";")
		{
			global_error(";",lex_sym);
			string testset[]={"","begin","const","var","begin","function","procedure"};
			parser_test(testset,6);
			if(lex_sym=="")
			{
				global_error("begin","nothing");
				return 0;
			}
		}
		else
			lex_getsym();
	}
	if(!parser_procedure())
	{
		string testset[]={"",";"};
		parser_test(testset,2);
		if(lex_sym!="")
		{
			global_error(";","nothing");
			return 0;
		}
	}
	if(lex_sym!=";")
	{
		global_error(";",lex_sym);
		return 0;
	}
	else
	lex_getsym();
	#ifdef PARSER_DEBUG
	cout << "函数声明" << endl;
	#endif
	return 1;
}
Beispiel #19
0
static int parser_constdefinition()//常量定义
{
	if(lex_sym=="ident")
	{
		string constname=lex_token;
		lex_getsym();
		if(lex_sym=="="||lex_sym==":=")
		{
			if(lex_sym==":=")
			{
				global_error("=",":=");//是=不是:=
			}
			lex_getsym();
			if(lex_sym=="char")
			{
				if(!symbtable_enter(constname,"const","char",lex_value,0))
					return 0;
				lex_getsym();

			}
			else if(lex_sym=="+"||lex_sym=="-")
			{
				int mark=lex_sym=="-"?-1:1;
				lex_getsym();
				if(lex_sym=="digit")
				{
					if(!symbtable_enter(constname,"const","integer",lex_value*mark,0))
						return 0;
					lex_getsym();
				}
				else
				{
					global_error("digit",lex_sym);//+-后面应该是数字
					return 0;
				}
			}
			else if(lex_sym=="digit")
			{
				if(!symbtable_enter(constname,"const","integer",lex_value,0))
					return 0;
				lex_getsym();
			}
			else
			{
				global_error("const's value",lex_sym);//常量都没定义明白就不填表了。
				return 0;
			}
		}
		else
		{
			global_error("=",lex_sym);//标识符后面是=
			return 0;
		}
	}
	else
	{
		global_error("ident",lex_sym);//常量定义开头是标识符
		return 0;
	}
	#ifdef PARSER_DEBUG
	cout << "常量定义" << endl;
	#endif
	return 1;
}
Beispiel #20
0
static int parser_vardefinition()
{
	int size=0;
	symbItem *start;
	string consttype;
	if(lex_sym=="ident")
	{
		if(!symbtable_enter(lex_token,"var","",0,0))
			return 0;
		start=symbtable_now->last_item;
		lex_getsym();
		while(lex_sym==",")
		{
			lex_getsym();
			if(lex_sym!="ident")
			{
				global_error("ident",lex_sym);
				return 0;
			}
			else
			{
				if(!symbtable_enter(lex_token,"var","",0,0))
					return 0;
				lex_getsym();
			}
		}
		if(lex_sym!=":")
		{
			global_error(":",lex_sym);
			return 0;
		}
		lex_getsym();
		if(lex_sym=="integer"||lex_sym=="char")
			consttype=lex_sym;
		else
		{
			if(lex_sym=="array")
			{
				if_array=1;
				lex_getsym();
				if(lex_sym!="[")
				{
					global_error("[",lex_sym);
					if_array=0;
					return 0;
				}
				else
					lex_getsym();
				if(lex_sym!="digit")
				{
					if_array=0;
					global_error("digit",lex_sym);
					return 0;
				}
				size=lex_value;
				lex_getsym();
				if(lex_sym!="]")
				{
					if_array=0;
					global_error("]",lex_sym);
					return 0;
				}
				else
					lex_getsym();
				if(lex_sym!="of")
				{
					global_error("of",lex_sym);
				}
				else
					lex_getsym();
				if(lex_sym=="integer"||lex_sym=="char")//这里你调试了很久
					consttype=lex_sym;
				else
				{
					global_error("integer or char",lex_sym);
					if_array=0;
					return 0;
				}
			}
			else//!array,!integer,!char
			{
				global_error("type",lex_sym);
					return 0;
			}
		}
		while(start!=NULL)
		{
			start->type=consttype;
			start->size=size;
			if(if_array)
			{
				start->kind="array";
			}
			start=start->link;
		}
		if_array=0;
		lex_getsym();
	}
	else
	{
		global_error("ident",lex_sym);//变量定义开头是标识符
		return 0;
	}
	#ifdef PARSER_DEBUG
	cout << "变量定义" << endl;
	#endif
	return 1;
}