--- parser3/src/main/compile.y 2001/02/25 09:03:17 1.40 +++ parser3/src/main/compile.y 2001/03/06 10:49:23 1.47 @@ -1,5 +1,5 @@ /* - $Id: compile.y,v 1.40 2001/02/25 09:03:17 paf Exp $ + $Id: compile.y,v 1.47 2001/03/06 10:49:23 paf Exp $ */ %{ @@ -83,22 +83,25 @@ control_method: '@' STRING '\n' file->APPEND_CONST(".p"); PC->request->use(file->cstr(), 0); } - } else if(name==PARENTS_NAME) { - for(int i=0; isize(); i+=2) { - String& parent_name=*SLA2S(strings_code, i); - VClass *parent=static_cast( - PC->request->classes().get(parent_name)); - if(!parent) { - strcpy(PC->error, parent_name.cstr()); - strcat(PC->error, ": undefined class in @"PARENTS_NAME); + } else if(name==BASE_NAME) { + if(strings_code->size()==1*2) { + String& base_name=*SLA2S(strings_code); + VClass *base=static_cast( + PC->request->classes().get(base_name)); + if(!base) { + strcpy(PC->error, base_name.cstr()); + strcat(PC->error, ": undefined class in @"BASE_NAME); YYERROR; } - PC->vclass->add_parent(*parent); + PC->vclass->set_base(*base); + } else { + strcpy(PC->error, "@"BASE_NAME" must contain sole name"); + YYERROR; } } else { strcpy(PC->error, name.cstr()); strcat(PC->error, ": invalid special name. valid names are " - CLASS_NAME", "USES_NAME" and "PARENTS_NAME); + CLASS_NAME", "USES_NAME" and "BASE_NAME); YYERROR; } } @@ -145,15 +148,16 @@ action: get | put | with | call; /* get */ -get: '$' any_name { +get: '$' get_name { $$=$2; /* stack: resulting value */ OP($$, OP_WRITE); /* value=pop; write(value) */ }; - -any_name: name_without_curly_rdive EON | name_in_curly_rdive; - +get_name: name_without_curly_rdive EON | name_in_curly_rdive; name_in_curly_rdive: '{' name_without_curly_rdive '}' { $$=$2 }; -name_without_curly_rdive: name_without_curly_rdive_read | name_without_curly_rdive_root; +name_without_curly_rdive: + name_without_curly_rdive_read +| name_without_curly_rdive_root +| name_without_curly_rdive_class; name_without_curly_rdive_read: name_without_curly_rdive_code { $$=N(POOL); Array *diving_code=$1; @@ -174,18 +178,22 @@ name_without_curly_rdive_root: ':' name_ OP($$, OP_WITH_ROOT); /* stack: starting context */ P($$, $2); /* diving code; stack: current context */ }; +name_without_curly_rdive_class: class_prefix name_without_curly_rdive_code { $$=$1; P($$, $2) }; name_without_curly_rdive_code: name_advance2 | name_path name_advance2 { $$=$1; P($$, $2) }; /* put */ -put: '$' name_expr_wdive '(' constructor_value ')' { +put: '$' name_expr_wdive '[' constructor_value ']' { $$=$2; /* stack: context,name */ P($$, $4); /* stack: context,name,constructor_value */ OP($$, OP_CONSTRUCT); /* value=pop; name=pop; context=pop; construct(context,name,value) */ }; -name_expr_wdive: name_expr_wdive_write | name_expr_wdive_root; +name_expr_wdive: + name_expr_wdive_write +| name_expr_wdive_root +| name_expr_wdive_class; name_expr_wdive_write: name_expr_dive_code { - $$=N(POOL); + $$=N(POOL); Array *diving_code=$1; String *first_name=SLA2S(diving_code); if(first_name && *first_name==SELF_NAME) { @@ -204,6 +212,7 @@ name_expr_wdive_root: ':' name_expr_dive OP($$, OP_WITH_ROOT); /* stack: starting context */ P($$, $2); /* diving code; stack: context,name */ }; +name_expr_wdive_class: class_prefix name_expr_dive_code { $$=$1; P($$, $2) }; constructor_value: constructor_one_param_value @@ -246,29 +255,17 @@ constructor_two_params_value: STRING ';' /* call */ call: '^' call_name store_params EON { /* ^field.$method{vasya} */ - $$=$2; /* with_xxx,diving code; stack: context,method_name */ + $$=$2; /* with_xxx,diving code; stack: context,method_junction */ OP($$, OP_GET_METHOD_FRAME); /* stack: context,method_frame */ P($$, $3); /* filling method_frame.store_params */ OP($$, OP_CALL); /* method_frame=pop; ncontext=pop; call(ncontext,method_frame) */ }; -call_name: name_without_curly_rdive | class_method_name; - -class_method_name: STRING ':' name_advance1 { - String& name=*SLA2S($1); - VClass *vclass=static_cast(PC->request->classes().get(name)); - if(!vclass) { - strcpy(PC->error, name.cstr()); - strcat(PC->error, ": undefined class in call"); - YYERROR; - } - $$=CL(vclass); - P($$, $3); -}; +call_name: name_without_curly_rdive; store_params: store_param | store_params store_param { $$=$1; P($$, $2) }; store_param: store_round_param | store_curly_param; -store_round_param: '(' store_param_parts ')' {$$=$2}; +store_round_param: '[' store_param_parts ']' {$$=$2}; store_param_parts: store_param_part | store_param_parts ';' store_param_part { $$=$1; P($$, $3) } @@ -342,6 +339,18 @@ subvar__get_write: '$' subvar_ref_name_r OP($$, OP_GET_ELEMENT__WRITE); }; +class_prefix: STRING ':' { + String& name=*SLA2S($1); + VClass *vclass=static_cast(PC->request->classes().get(name)); + if(!vclass) { + strcpy(PC->error, "'"); + strcat(PC->error, name.cstr()); + strcat(PC->error, "' class is undefined in call"); + YYERROR; + } + $$=CL(vclass); // vclass +}; + /* with */ @@ -414,7 +423,7 @@ int yylex(YYSTYPE *lvalp, void *pc) { char next_c=*PC->source; if(next_c=='^' || next_c=='$' || next_c==';' || - next_c=='(' || next_c==')' || + next_c=='[' || next_c==']' || next_c=='{' || next_c=='}') { if(end!=begin) { // append piece till ^ @@ -517,7 +526,8 @@ int yylex(YYSTYPE *lvalp, void *pc) { case LS_VAR_NAME_SIMPLE: if(c==0 || c==' '|| c=='\t' || c=='\n' || - c==')' || c=='}') { + c==';' || + c==']' || c=='}') { pop_LS(PC); PC->source--; if(--PC->col<0) { PC->line--; PC->col=-1; } result=EON; @@ -528,7 +538,7 @@ int yylex(YYSTYPE *lvalp, void *pc) { result=c; goto break2; } - if(c=='(') { + if(c=='[') { PC->ls=LS_VAR_ROUND; lexical_brackets_nestage=1; result=c; @@ -571,7 +581,7 @@ int yylex(YYSTYPE *lvalp, void *pc) { result=c; goto break2; } - if(c==')') { + if(c==']') { if(--lexical_brackets_nestage==0) { pop_LS(PC); result=c; @@ -582,7 +592,7 @@ int yylex(YYSTYPE *lvalp, void *pc) { result=c; goto break2; } - if(c=='(') + if(c=='[') lexical_brackets_nestage++; break; case LS_VAR_CURLY: @@ -608,7 +618,7 @@ int yylex(YYSTYPE *lvalp, void *pc) { // METHOD CALL case LS_METHOD_NAME: - if(c=='(') { + if(c=='[') { PC->ls=LS_METHOD_ROUND; lexical_brackets_nestage=1; result=c; @@ -642,13 +652,13 @@ int yylex(YYSTYPE *lvalp, void *pc) { result=c; goto break2; } - if(c==')') + if(c==']') if(--lexical_brackets_nestage==0) { PC->ls=LS_METHOD_AFTER; result=c; goto break2; } - if(c=='(') + if(c=='[') lexical_brackets_nestage++; break; case LS_METHOD_CURLY: @@ -672,7 +682,7 @@ int yylex(YYSTYPE *lvalp, void *pc) { lexical_brackets_nestage++; break; case LS_METHOD_AFTER: - if(c=='(') {/* )( }( */ + if(c=='[') {/* )( }( */ PC->ls=LS_METHOD_ROUND; lexical_brackets_nestage=1; result=c; @@ -708,7 +718,7 @@ break2: PC->string->APPEND(begin, end-begin, PC->file, begin_line/*, start_col*/); } // create STRING value: array of OP_VALUE+vstring - *lvalp=SL(NEW VString(PC->string)); + *lvalp=SL(NEW VString(*PC->string)); // new pieces storage PC->string=NEW String(POOL); // go! @@ -720,7 +730,7 @@ int real_yyerror(parse_control *pc, char { //fprintf(stderr, "[%s]\n", s); - s[MAX_STRING-1]=0; strcpy(pc->error, s); + strncpy(pc->error, s, MAX_STRING); // TODO: перепроверить с треклятым последним байтом return 1; }