Ejemplo n.º 1
0
/**
   Test the parser
*/
static void test_parser()
{
	say( L"Testing parser" );
	
	
	say( L"Testing null input to parser" );
	if( !parser_test( 0, 0, 0, 0 ) )
	{
		err( L"Null input to parser_test undetected" );
	}

	say( L"Testing block nesting" );
	if( !parser_test( L"if; end", 0, 0, 0 ) )
	{
		err( L"Incomplete if statement undetected" );			
	}
	if( !parser_test( L"if test; echo", 0, 0, 0 ) )
	{
		err( L"Missing end undetected" );			
	}
	if( !parser_test( L"if test; end; end", 0, 0, 0 ) )
	{
		err( L"Unbalanced end undetected" );			
	}

	say( L"Testing detection of invalid use of builtin commands" );
	if( !parser_test( L"case foo", 0, 0, 0 ) )
	{
		err( L"'case' command outside of block context undetected" );		
	}
	if( !parser_test( L"switch ggg; if true; case foo;end;end", 0, 0, 0 ) )
	{
		err( L"'case' command outside of switch block context undetected" );		
	}
	if( !parser_test( L"else", 0, 0, 0 ) )
	{
		err( L"'else' command outside of conditional block context undetected" );		
	}
	if( !parser_test( L"break", 0, 0, 0 ) )
	{
		err( L"'break' command outside of loop block context undetected" );		
	}
	if( !parser_test( L"exec ls|less", 0, 0, 0 ) || !parser_test( L"echo|return", 0, 0, 0 ))
	{
		err( L"Invalid pipe command undetected" );		
	}	

	say( L"Testing basic evaluation" );
	if( !eval( 0, 0, TOP ) )
	{
		err( L"Null input when evaluating undetected" );
	}	
	if( !eval( L"ls", 0, WHILE ) )
	{
		err( L"Invalid block mode when evaluating undetected" );
	}
	
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
Archivo: main.c Proyecto: turnage/Charl
/**
 *  Call module tests with verbose reporting.
 */
int test (void)
{
        int report, count = 0;

        printf("\nPerforming tests\n");
        printf("-----------------------------------------------------------\n");

        printf("Crypto module......................................");
        if (!(report = crypto_test()))
                printf("....[OK]\n");
        else {
                printf("[%6d]\n", report);
                count += 1;
        }

        printf("Client module......................................");
        if (!(report = client_test()))
                printf("....[OK]\n");
        else {
                printf("[%6d]\n", report);
                count += 1;
        }

        printf("Parser module......................................");
        if (!(report = parser_test()))
                printf("....[OK]\n");
        else {
                printf("[%6d]\n", report);
                count += 1;
        }

        printf("-----------------------------------------------------------\n");

        return count;
}
Ejemplo n.º 5
0
int main( int argc, char **argv ){
  
 parser_check( 1.0 + 2.0 );
 parser_check( -1.e-03 + 2E+1 );
 parser_check( asin( sin( 1.0 ) ) );
 parser_check( pow( sin(1.0), 2.0 ) + pow( cos(1.0), 2.0 ) );
 parser_check( (0.1 + 4.9)*(2.5*2)*(-3.0-2.0) );
 parser_check( log( exp( 25.0 ) ) );
 
 parser_test( "2^2^3" );
 parser_test( "sin(1.0)^2 + cos(1.0)^2" );
 parser_test( "2^-2" );
 parser_test( "2^-(2.0*fabs(-sqrt(sin(0.5)^2 + cos(0.5)^2)))" );
   
 return 0;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
int main(int argc, char** argv)
{
    parser_test();
    parser_test2();

    template_test();

    system("pause");
}
Ejemplo n.º 9
0
int main()
{
	scanner_test();
	parser_test();
	random_messages_test();
	utils_test();

	return 0;
}
Ejemplo n.º 10
0
int main(int argc, char *argv[])
{
	plan_lazy();

	scheme_find_test();
	parser_test();
	str_test();

	return 0;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
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");
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
0
/* main function for debug issuing a number of tests                     */
int main()
{
	setenv("a","var1",true);
	setenv("b","var2",true);
	setenv("c","var3",true);

	parser_test("");
	parser_test("exit");
	parser_test("cd ..");
	parser_test("cd exit");
	parser_test("cd foo next arguments are ignored");
	parser_test("ls -l");
	parser_test("cat; ls foo");
	parser_test("cat; ; ls foo");
	parser_test("ls -l -a -r   \n   cd \n echo foobar");
	parser_test(">file ls");
	parser_test("> out <in cat & echo foo");
	parser_test("missing file >& cd ..");
	parser_test("missing file <; exit");
	parser_test("ls <in -lisa | grep '.pdf' | sort >out");
	parser_test("ls > foo | grep .pdf    | sort");
	parser_test("ls | <foo grep .pdf |   sort");
	parser_test("ls | grep .pdf >bar |   sort");
	parser_test("cd .. | ls");
	parser_test("ls | exit | sort");
	parser_test("ls | sort | cd /bar/foo");
	parser_test("# this is a comment");
	parser_test("> out echo bla # this is a comment echo; $foo; 'open quote \n ls -l");
	parser_test("echo '; >foo <bar exit cd & \n $a | &' & ls -lisa" );
	parser_test("echo escaping \\\\ \\a \\< foo \\> bar \\; \\| \\$a \\& hello");
	parser_test("open 'quotation\n is still open");
	parser_test("open escaped char \\");
	parser_test("setenv foo 'bar and barfoo' this is ignored up to here; exit");
	parser_test("setenv foo");
	parser_test("unsetenv foo and this is ignored up to here; exit");
	parser_test("unsetenv");
	parser_test("$a> $b& cd ..; exit");
	parser_test("${here <foobar");
	parser_test("echo alloneide'bla'blub\\#\\;$a${b}$c'yeah'");
	parser_test("jobs 13 ignored; bg 1 ignored; fg 3 igno red; bg; fg");
	parser_test("jobs foobar");
	parser_test("bg -42");
	parser_test("fg dunno");

	return EXIT_SUCCESS;
}
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
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;
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
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;
}
Ejemplo n.º 19
0
/**
   The complete builtin. Used for specifying programmable
   tab-completions. Calls the functions in complete.c for any heavy
   lifting. Defined in builtin_complete.c
*/
static int builtin_complete( wchar_t **argv )
{
	int res=0;
	int argc=0;
	int result_mode=SHARED;
	int remove = 0;
	int authoritative = -1;
	int flags = COMPLETE_AUTO_SPACE;
	
	string_buffer_t short_opt;
	array_list_t gnu_opt, old_opt;
	wchar_t *comp=L"", *desc=L"", *condition=L"";

	wchar_t *do_complete = 0;
	
	array_list_t cmd;
	array_list_t path;

	static int recursion_level=0;
	
	if( !is_interactive_session )
	{
		debug( 1, _(L"%ls: Command only available in interactive sessions"), argv[0] );
	}
	
	al_init( &cmd );
	al_init( &path );
	sb_init( &short_opt );
	al_init( &gnu_opt );
	al_init( &old_opt );
	
	argc = builtin_count_args( argv );	
	
	woptind=0;
	
	while( res == 0 )
	{
		const static struct woption
			long_options[] =
			{
				{
					L"exclusive", no_argument, 0, 'x' 
				}
				,
				{
					L"no-files", no_argument, 0, 'f' 
				}
				,
				{
					L"require-parameter", no_argument, 0, 'r' 
				}
				,
				{
					L"path", required_argument, 0, 'p'
				}
				,					
				{
					L"command", required_argument, 0, 'c' 
				}
				,					
				{
					L"short-option", required_argument, 0, 's' 
				}
				,
				{
					L"long-option", required_argument, 0, 'l'
				}
				,
				{
					L"old-option", required_argument, 0, 'o' 
				}
				,
				{
					L"description", required_argument, 0, 'd'
				}
				,
				{
					L"arguments", required_argument, 0, 'a'
				}
				,
				{
					L"erase", no_argument, 0, 'e'
				}
				,
				{
					L"unauthoritative", no_argument, 0, 'u'
				}
				,
				{
					L"authoritative", no_argument, 0, 'A'
				}
				,
				{
					L"condition", required_argument, 0, 'n'
				}
				,
				{
					L"do-complete", optional_argument, 0, 'C'
				}
				,
				{
					L"help", no_argument, 0, 'h'
				}
				,
				{ 
					0, 0, 0, 0 
				}
			}
		;		
		
		int opt_index = 0;
		
		int opt = wgetopt_long( argc,
								argv, 
								L"a:c:p:s:l:o:d:frxeuAn:C::h", 
								long_options, 
								&opt_index );
		if( opt == -1 )
			break;
			
		switch( opt )
		{
			case 0:
				if(long_options[opt_index].flag != 0)
					break;
                sb_printf( sb_err,
                           BUILTIN_ERR_UNKNOWN,
                           argv[0],
                           long_options[opt_index].name );
				builtin_print_help( argv[0], sb_err );

				
				res = 1;
				break;
				
			case 'x':					
				result_mode |= EXCLUSIVE;
				break;
					
			case 'f':					
				result_mode |= NO_FILES;
				break;
				
			case 'r':					
				result_mode |= NO_COMMON;
				break;
					
			case 'p':	
			case 'c':
			{
				wchar_t *a = unescape( woptarg, 1);
				if( a )
				{
					al_push( (opt=='p'?&path:&cmd), a );
				}
				else
				{
					sb_printf( sb_err, L"%ls: Invalid token '%ls'\n", argv[0], woptarg );
					res = 1;					
				}				
				break;
			}
				
			case 'd':
				desc = woptarg;
				break;
				
			case 'u':
				authoritative=0;
				break;
				
			case 'A':
				authoritative=1;
				break;
				
			case 's':
				sb_append( &short_opt, woptarg );
				break;
					
			case 'l':
				al_push( &gnu_opt, woptarg );
				break;
				
			case 'o':
				al_push( &old_opt, woptarg );
				break;

			case 'a':
				comp = woptarg;
				break;
				
			case 'e':
				remove = 1;
				break;

			case 'n':
				condition = woptarg;
				break;
				
			case 'C':
				do_complete = woptarg?woptarg:reader_get_buffer();
				break;
				
			case 'h':
				builtin_print_help( argv[0], sb_out );
				return 0;
				
			case '?':
				builtin_unknown_option( argv[0], argv[woptind-1] );
				res = 1;
				break;
				
		}
		
	}

	if( !res )
	{
		if( condition && wcslen( condition ) )
		{
			if( parser_test( condition, 0, 0, 0 ) )
			{
				sb_printf( sb_err,
						   L"%ls: Condition '%ls' contained a syntax error\n", 
						   argv[0],
						   condition );
				
				parser_test( condition, 0, sb_err, argv[0] );
				
				res = 1;
			}
		}
	}
	
	if( !res )
	{
		if( comp && wcslen( comp ) )
		{
			if( parser_test_args( comp, 0, 0 ) )
			{
				sb_printf( sb_err,
						   L"%ls: Completion '%ls' contained a syntax error\n", 
						   argv[0],
						   comp );
				
				parser_test_args( comp, sb_err, argv[0] );
				
				res = 1;
			}
		}
	}

	if( !res )
	{
		if( do_complete )
		{
			array_list_t *comp;
			int i;

			const wchar_t *prev_temporary_buffer = temporary_buffer;

			wchar_t *token;

			parse_util_token_extent( do_complete, wcslen( do_complete ), &token, 0, 0, 0 );
						
			temporary_buffer = do_complete;		

			if( recursion_level < 1 )
			{
				recursion_level++;
			
				comp = al_halloc( 0 );
			
				complete( do_complete, comp );
			
				for( i=0; i<al_get_count( comp ); i++ )
				{
					completion_t *next = (completion_t *)al_get( comp, i );
					wchar_t *prepend;
					
					if( next->flags & COMPLETE_NO_CASE )
					{
						prepend = L"";
					}
					else
					{
						prepend = token;
					}
						

					if( next->description )
					{
						sb_printf( sb_out, L"%ls%ls\t%ls\n", prepend, next->completion, next->description );
					}
					else
					{
						sb_printf( sb_out, L"%ls%ls\n", prepend, next->completion );
					}
				}
			
				halloc_free( comp );
				recursion_level--;
			}
		
			temporary_buffer = prev_temporary_buffer;		
		
		}
		else if( woptind != argc )
		{
			sb_printf( sb_err, 
					   _( L"%ls: Too many arguments\n" ),
					   argv[0] );
			builtin_print_help( argv[0], sb_err );

			res = 1;
		}
		else if( (al_get_count( &cmd) == 0 ) && (al_get_count( &path) == 0 ) )
		{
			/* No arguments specified, meaning we print the definitions of
			 * all specified completions to stdout.*/
			complete_print( sb_out );		
		}
		else
		{
			if( remove )
			{
				builtin_complete_remove( &cmd,
										 &path,
										 (wchar_t *)short_opt.buff,
										 &gnu_opt,
										 &old_opt );									 
			}
			else
			{
				builtin_complete_add( &cmd, 
									  &path,
									  (wchar_t *)short_opt.buff,
									  &gnu_opt,
									  &old_opt, 
									  result_mode, 
									  authoritative,
									  condition,
									  comp,
									  desc,
									  flags ); 
			}

		}	
	}
	
	al_foreach( &cmd, &free );
	al_foreach( &path, &free );

	al_destroy( &cmd );
	al_destroy( &path );
	sb_destroy( &short_opt );
	al_destroy( &gnu_opt );
	al_destroy( &old_opt );

	return res;
}
Ejemplo n.º 20
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;
}