/** 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" ); } }
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; }
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; }
/** * 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; }
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; }
static int parser_formalparalist(int ¶_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; }
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; }
int main(int argc, char** argv) { parser_test(); parser_test2(); template_test(); system("pause"); }
int main() { scanner_test(); parser_test(); random_messages_test(); utils_test(); return 0; }
int main(int argc, char *argv[]) { plan_lazy(); scheme_find_test(); parser_test(); str_test(); return 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; }
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"); }
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; }
/* 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; }
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; }
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; }
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; }
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; }
/** 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; }
//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&¶s.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; }