#include "semcheck.h" /**************************************************************** ** File Name : sem_check.c ** ** ** ** check_regular_partclass ** ** check regular class (without label) can not have ** ** no capital character in its name. ** ** check_cpp_keyw(int &result ) ** ** ** ** is_first_cons ** ** the first production is a construction production. ** ** define_once ** ** every class is defined once and only once,including ** ** actual arguments. ** ** rep_identical ** ** the two instances on r.h.s. of repetition production** ** are identical. ** ** match_parameters ** ** #formal parameters = #actual parameters ** ** check_formal_pars ** ** Actual parameters for formal class parameters must ** ** be non-parameterized classes. ** ** alt_common_pars ** ** For a parameterized alternation class,all its ** ** alternatives have to use all its formal parameters ** ** in the same order ** ** proper_alternatives ** ** All alternatives must be defined by construction ** ** classes or by alternation classes that will ** ** eventually be defined by construction classes. ** ** Since we will check alternation cycles,and cyclefree** ** properties,we can simpliify the task checking that ** ** all the alternatives can be repetition classes. ** ** cycle_free_inherit ** ** There is no alternation cycle. ** ** exp_param ** ** expand parameterization ** ** expand_inherit ** ** expand inherit ** ** UNIQUE_LABELS ** ** The names of parts are unique ** ** ***Before this,we have to check that there is no ** ** alternation cycle. ** ** ***repetition classes can not be subclasses. ** ** COMMON_EXPANSION ** ** expand common parts ** ** ** ** CYCLE_FREE_SUBGRAPH ** ** Every vertex has a cycle-free subgraph. ** ** ** ** LEFT_RECURSION_FREE ** ** There is no left-recursion in class-dictionary ** ** ** ** CHECK_LL1 ** ** ** ** LL1_enforcer ** ** ** ** Date : 6/7/90 Cun ** ** Update Date : 2/7/91 Cun ** ** ** *****************************************************************/ int finalresult = 0; extern Vertex_Comma_list * terminals; int Demeter_in::sem_check(int doll, int nointer) { int result = input->sem_check(doll,nointer); this->emit_final_msg(result,sem_out); return(result); } int Input::sem_check(int doll, int nointer) { return 0; } void Cd_graph::set_default_terminal_sets() { int NUMBER_OF_TERMINAL_SETS =5; char *df1 = "DemNumber"; char *df2 = "DemIdent"; char *df3 = "DemString"; char *df4 = "DemReal"; char *df5 = "DemText"; char *default_terminal_sets[6]; default_terminal_sets[0] = df1; default_terminal_sets[1] = df2; default_terminal_sets[2] = df3; default_terminal_sets[3] = df4; default_terminal_sets[4] = df5; if (this->get_terminal_sets()) { terminals = this->get_terminal_sets(); return; } Vertex_Comma_list *new_sets = new Vertex_Comma_list(); int total_num = NUMBER_OF_TERMINAL_SETS; while (total_num) { total_num--; new_sets->append(new Vertex( new DemIdent( default_terminal_sets[total_num]))); } this->rset_terminal_sets(new_sets); terminals = this->get_terminal_sets(); } int Cd_graph::sem_check(int doll, int nointer) { char * msg_regular = "\nChecking that if a class is used without a label, then the name of\nthis class must contain at least one capital letter ..."; char * msg_cpp = "\nChecking whether the class names and label names are\n the keywords of C++ Demeter..."; char * msg_cons = "\nChecking that the first production is an\n unparameterized construction production ..."; char * msg_define = "\nChecking that every class is defined exactly once ..."; char * msg_rep = "\nChecking that two class names on the right hand side\n of every repetition production are identical ..."; char * msg_match = "\nChecking that every parameterized class is consistently\n defined and used ..."; char * msg_formal = "\nChecking that formal parameter classes are not used as \n parameterized classes on the right hand side ..."; char * msg_alt_com = "\nChecking that every alternative of a parameterized\n alternation class has to use all its formal\n parameters in the same order ..."; char * msg_proper = "\nChecking that all alternatives are defined as either\n construction classes or alternation classes that \n will eventually be defined by construction classes ..."; char * msg_cycle_inh = "\nChecking inheritance cycles ..."; char * msg_exp_par = "\nExpanding parameterization ..."; char * msg_exp_com = "\nExpanding common parts ..."; char * msg_exp_inh = "\nExpanding inherit classes ..."; char * msg_unique = "\nChecking that the part names of every vertex are unique ..."; int result = 0; this->set_default_terminal_sets(); /* check that external classes and types cannot be alternatives, parameters ... */ this->pick_extern_types(finalresult); this->emit_intro_msg(msg_regular,sem_out); /*check the names of the vertices without labels */ result = this->check_regular_partclass(); if (result!=SUCCESS) finalresult = finalresult + result; this->emit_intro_msg(msg_cons,sem_out); /* check that the first production is of a construction vertex. */ result = this->is_first_cons(); if (result!=SUCCESS) finalresult = finalresult + result; if (result!=SUCCESS) return (finalresult); this->emit_intro_msg(msg_define,sem_out); result = this->define_once(); if (result!=SUCCESS) finalresult = finalresult + result; if (result!=SUCCESS) return (finalresult); this->emit_intro_msg(msg_rep,sem_out); result = this->rep_identical(); if (result!=SUCCESS) finalresult = finalresult + result; this->emit_intro_msg(msg_match,sem_out); result = this->match_parameters(); if (result!=SUCCESS) finalresult = finalresult + result; this->emit_intro_msg(msg_formal,sem_out); result = this->check_formal_pars(); if (result!=SUCCESS) finalresult = finalresult + result; if (result!=SUCCESS) return (finalresult); this->emit_intro_msg(msg_alt_com,sem_out); result = this->alt_common_pars(); if (result!=SUCCESS) finalresult = finalresult + result; this->emit_intro_msg(msg_cycle_inh,sem_out); result = this->cycle_free_inherit(); if (result!=SUCCESS) finalresult = finalresult + result; if (result!=SUCCESS) return (finalresult); /* Expand parameterized vertices */ this->emit_intro_msg(msg_exp_par,sem_out); Cd_graph *par_expanded_cd = this->exp_param(); par_expanded_cd->addLabelToRegular(); if (!nointer) { char *tmp; tmp = tmpfname(); ofstream cd_param_exp_tmp(tmp); if (!cd_param_exp_tmp) { cerr << toolname << ": unable to open " << tmp << " for output." << endl; exit(1); } cd_param_exp_tmp << "// Parameterization-expanded class dictionary.\n" << endl; par_expanded_cd->cd_pp(cd_param_exp_tmp); cd_param_exp_tmp.close(); mv_if_change(mv_interactive,tmp,"notmod/cds/cd-param-exp"); free(tmp); } this->emit_intro_msg(msg_proper,sem_out); result = par_expanded_cd->proper_alternatives(); if (result!=SUCCESS) finalresult = finalresult + result; if (result!=SUCCESS) return (finalresult); /* check keywords */ this->emit_intro_msg(msg_cpp,sem_out); par_expanded_cd->check_cpp_keyw(NULL,result); if (result!=SUCCESS) finalresult = finalresult + result; this->emit_intro_msg(msg_exp_com,sem_out); Cd_graph *common_expanded_cd = par_expanded_cd->COMMON_EXPANSION(); this->emit_intro_msg(msg_exp_inh,sem_out); common_expanded_cd->expand_inherit(); if (!nointer) { char *tmp; tmp = tmpfname(); ofstream cd_inh_exp_tmp(tmp); if (!cd_inh_exp_tmp) { cerr << toolname << ": unable to open " << tmp << " for output." << endl; exit(1); } cd_inh_exp_tmp << "// Inherit-class-expanded class dictionary.\n" << endl; common_expanded_cd->cd_pp(cd_inh_exp_tmp); cd_inh_exp_tmp.close(); mv_if_change(mv_interactive,tmp,"notmod/cds/cd-inh-exp"); free(tmp); } Cd_graph * inherit_expanded_cd = common_expanded_cd; this->emit_intro_msg(msg_unique,sem_out); Cd_graph *unique_labels_cd = inherit_expanded_cd->UNIQUE_LABELS(result); if (result!=SUCCESS) finalresult = finalresult + result; if (!nointer) { char *tmp; tmp = tmpfname(); ofstream cd_com_exp_tmp(tmp); if (!cd_com_exp_tmp) { cerr << toolname << ": unable to open " << tmp << " for output." << endl; exit(1); } cd_com_exp_tmp << "// Common-expanded class dictionary\n" << endl; unique_labels_cd->cd_pp(cd_com_exp_tmp); cd_com_exp_tmp.close(); mv_if_change(mv_interactive,tmp,"notmod/cds/cd-com-exp"); free(tmp); tmp = tmpfname(); ofstream cd_parse_tmp(tmp); if (!cd_parse_tmp) { cerr << toolname << ": unable to open " << tmp << " for output." << endl; exit(1); } cd_parse_tmp << "// Class dictionary (cd-parse) for parsing\n" << endl; unique_labels_cd->cd_pp(cd_parse_tmp); cd_parse_tmp.close(); mv_if_change(mv_interactive,tmp,"notmod/cds/cd-parse"); free(tmp); tmp = tmpfname(); ofstream cd_print_tmp(tmp); if (!cd_print_tmp) { cerr << toolname << ": unable to open " << tmp << " for output." << endl; exit(1); } cd_print_tmp << "// Class dictionary (cd-print) for printing\n" << endl; unique_labels_cd->cd_pp(cd_print_tmp); cd_print_tmp.close(); mv_if_change(mv_interactive,tmp,"notmod/cds/cd-print"); free(tmp); } /************************************************************************* * strip off external classes * **************************************************************************/ unique_labels_cd->strip_extern(); Cd_graph *stripped_cd = unique_labels_cd; /* if (stripped_cd->CYCLE_FREE_SUBGRAPH_START(unique_labels_cd)==FALSE)*/ if (stripped_cd->CYCLE_FREE_SUBGRAPH_START()==FALSE) ;/* finalresult = finalresult + ERROR_CFSG; */ if (doll) { Cd_graph * cdwithffsets; if (stripped_cd->LEFT_RECURSION_FREE()) { int r = TRUE; cdwithffsets = stripped_cd->CHECK_LL1(r, nointer); if (!nointer) { if (r==FALSE) { cdwithffsets->LL1_enforcer(FALSE); } /* finalresult = finalresult + ERROR_LL1; */ else cdwithffsets->LL1_enforcer(1); } } else { /* finalresult = finalresult + ERROR_LL1; */ cout << "\n You cannot use the generic parser unless you eliminate left recursion.\n" << endl; } } return (finalresult); }