--- parser3/src/main/compile.y 2015/03/16 09:47:34 1.267 +++ parser3/src/main/compile.y 2016/05/18 22:27:28 1.276 @@ -2,13 +2,13 @@ /** @file Parser: compiler(lexical parser and grammar). - Copyright (c) 2001-2012 Art. Lebedev Studio (http://www.artlebedev.com) + Copyright (c) 2001-2015 Art. Lebedev Studio (http://www.artlebedev.com) Author: Alexander Petrosyan (http://design.ru/paf) */ -volatile const char * IDENT_COMPILE_Y = "$Id: compile.y,v 1.267 2015/03/16 09:47:34 misha Exp $"; +volatile const char * IDENT_COMPILE_Y = "$Id: compile.y,v 1.276 2016/05/18 22:27:28 moko Exp $"; /** @todo parser4: @@ -22,12 +22,12 @@ volatile const char * IDENT_COMPILE_Y = */ #define YYSTYPE ArrayOperation* -#define YYPARSE_PARAM pc -#define YYLEX_PARAM pc #define YYDEBUG 1 -#define YYERROR_VERBOSE 1 -#define yyerror(msg) real_yyerror((Parse_control *)pc, msg) +#define YYERROR_VERBOSE 1 +#define yyerror(pc, msg) real_yyerror(pc, msg) #define YYPRINT(file, type, value) yyprint(file, type, value) +#define YYMALLOC pa_malloc +#define YYFREE pa_free // includes @@ -59,20 +59,22 @@ static const VString vempty; // local convinient inplace typecast & var #undef PC -#define PC (*(Parse_control *)pc) +#define PC (*pc) #undef POOL #define POOL (*PC.pool) #ifndef DOXYGEN #define CLASS_ADD if(PC.class_add()){ \ - strncpy(PC.error, PC.cclass->name().cstr(), MAX_STRING/2); \ + strncpy(PC.error, PC.cclass->type(), MAX_STRING/2); \ strcat(PC.error, " - class is already defined"); \ YYERROR; \ } %} -%pure_parser +%pure-parser +%lex-param {Parse_control* pc} +%parse-param {Parse_control* pc} %token EON %token STRING @@ -82,7 +84,6 @@ static const VString vempty; %token BAD_HEX_LITERAL %token BAD_METHOD_DECL_START %token BAD_METHOD_PARAMETER_NAME_CHARACTER -%token BAD_NONWHITESPACE_CHARACTER_IN_EXPLICIT_RESULT_MODE %token LAND "&&" %token LOR "||" @@ -169,27 +170,29 @@ control_method: '@' STRING '\n' // creating the class VStateless_class* cclass=new VClass; PC.cclass_new=cclass; - PC.cclass_new->set_name(name); + PC.cclass_new->set_type(name.cstr()); PC.append=false; } else { - strcpy(PC.error, "@"CLASS_NAME" must contain only one line with class name (contains more then one)"); + strcpy(PC.error, "@" CLASS_NAME " must contain only one line with class name (contains more then one)"); YYERROR; } } else if(command==USE_CONTROL_METHOD_NAME) { CLASS_ADD; - for(size_t i=0; icount(); i+=OPERATIONS_PER_OPVALUE) - PC.request.use_file(PC.request.main_class, LA2S(*strings_code, i)->trim(String::TRIM_END), PC.request.get_used_filename(PC.file_no)); + for(size_t i=0; icount(); i+=OPERATIONS_PER_OPVALUE){ + PC.request.use_file(PC.request.main_class, LA2S(*strings_code, i)->trim(String::TRIM_END), + PC.request.get_used_filename(PC.file_no), strings_code->get(i+1).origin); + } } else if(command==BASE_NAME) { if(PC.append){ strcpy(PC.error, "can't set base while appending methods to class '"); - strncat(PC.error, PC.cclass->name().cstr(), MAX_STRING/2); + strncat(PC.error, PC.cclass->type(), MAX_STRING/2); strcat(PC.error, "'"); YYERROR; } CLASS_ADD; if(PC.cclass->base_class()) { // already changed from default? strcpy(PC.error, "class already have a base '"); - strncat(PC.error, PC.cclass->base_class()->name().cstr(), MAX_STRING/2); + strncat(PC.error, PC.cclass->base_class()->type(), MAX_STRING/2); strcat(PC.error, "'"); YYERROR; } @@ -199,22 +202,22 @@ control_method: '@' STRING '\n' // @CLASS == @BASE sanity check if(VStateless_class *base_class=base_class_value->get_class()) { if(PC.cclass==base_class) { - strcpy(PC.error, "@"CLASS_NAME" equals @"BASE_NAME); + strcpy(PC.error, "@" CLASS_NAME " equals @" BASE_NAME); YYERROR; } PC.cclass->get_class()->set_base(base_class); } else { // they asked to derive from a class without methods ['env' & co] strcpy(PC.error, base_name.cstr()); - strcat(PC.error, ": you can not derive from this class in @"BASE_NAME); + strcat(PC.error, ": you can not derive from this class in @" BASE_NAME); YYERROR; } } else { strcpy(PC.error, base_name.cstr()); - strcat(PC.error, ": undefined class in @"BASE_NAME); + strcat(PC.error, ": undefined class in @" BASE_NAME); YYERROR; } } else { - strcpy(PC.error, "@"BASE_NAME" must contain sole name"); + strcpy(PC.error, "@" BASE_NAME " must contain sole name"); YYERROR; } } else if(command==OPTIONS_CONTROL_METHOD_NAME) { @@ -227,7 +230,7 @@ control_method: '@' STRING '\n' if(VStateless_class* existed=PC.get_existed_class(PC.cclass_new)){ if(!PC.reuse_existed_class(existed)){ strcpy(PC.error, "can't append methods to '"); - strncat(PC.error, PC.cclass_new->name().cstr(), MAX_STRING/2); + strncat(PC.error, PC.cclass_new->type(), MAX_STRING/2); strcat(PC.error, "' - the class wasn't marked as partial"); YYERROR; } @@ -236,7 +239,7 @@ control_method: '@' STRING '\n' PC.cclass_new->set_partial(); } } else { - strcpy(PC.error, "'"OPTION_PARTIAL_CLASS"' option should be used straight after @"CLASS_NAME); + strcpy(PC.error, "'" OPTION_PARTIAL_CLASS "' option should be used straight after @" CLASS_NAME); YYERROR; } } else if(option==method_call_type_static){ @@ -247,8 +250,8 @@ control_method: '@' STRING '\n' strcpy(PC.error, "'"); strncat(PC.error, option.cstr(), MAX_STRING/2); strcat(PC.error, "' invalid option. valid options are " - "'"OPTION_PARTIAL_CLASS"', '"OPTION_ALL_VARS_LOCAL_NAME"'" - ", '"METHOD_CALL_TYPE_STATIC"' and '"METHOD_CALL_TYPE_DYNAMIC"'" + "'" OPTION_PARTIAL_CLASS "', '" OPTION_ALL_VARS_LOCAL_NAME "'" + ", '" METHOD_CALL_TYPE_STATIC "' and '" METHOD_CALL_TYPE_DYNAMIC "'" ); YYERROR; } @@ -257,7 +260,7 @@ control_method: '@' STRING '\n' strcpy(PC.error, "'"); strncat(PC.error, command.cstr(), MAX_STRING/2); strcat(PC.error, "' invalid special name. valid names are " - "'"CLASS_NAME"', '"USE_CONTROL_METHOD_NAME"', '"BASE_NAME"' and '"OPTIONS_CONTROL_METHOD_NAME"'."); + "'" CLASS_NAME "', '" USE_CONTROL_METHOD_NAME "', '" BASE_NAME "' and '" OPTIONS_CONTROL_METHOD_NAME "'."); YYERROR; } }; @@ -584,7 +587,11 @@ call_value: '^' { && (*var_code)[0].code==OP::OP_VALUE__GET_CLASS && (*var_code)[3].code==OP::OP_PREPARE_TO_CONSTRUCT_OBJECT && (*var_code)[4].code==OP::OP_VALUE +#ifdef FEATURE_GET_ELEMENT4CALL + && (*var_code)[7].code==OP::OP_GET_ELEMENT4CALL +#else && (*var_code)[7].code==OP::OP_GET_ELEMENT +#endif ){ $$=N(); O(*$$, OP::OP_CONSTRUCT_OBJECT); @@ -599,7 +606,21 @@ call_value: '^' { } }; -call_name: name_without_curly_rdive; +call_name: name_without_curly_rdive { +#ifdef FEATURE_GET_ELEMENT4CALL + size_t count=$1->count(); + if(count){ + $$=$1; +#ifdef OPTIMIZE_BYTECODE_GET_OBJECT_ELEMENT + !(count==5 && change_first(*$$, OP::OP_GET_OBJECT_ELEMENT, OP::OP_GET_OBJECT_ELEMENT4CALL)) && +#endif +#ifdef OPTIMIZE_BYTECODE_GET_OBJECT_VAR_ELEMENT + !(count==5 && change_first(*$$, OP::OP_GET_OBJECT_VAR_ELEMENT, OP::OP_GET_OBJECT_VAR_ELEMENT4CALL)) && +#endif + !change(*$$, count-1, OP::OP_GET_ELEMENT, OP::OP_GET_ELEMENT4CALL); + } +#endif +}; store_params: store_param | store_params store_param { $$=$1; P(*$$, *$2); }; store_param: @@ -737,7 +758,7 @@ class_static_prefix: STRING ':' { $$=$1; // stack: class name string if(*LA2S(*$$) == BASE_NAME) { // pseudo BASE class if(VStateless_class* base=PC.cclass->base_class()) { - change_string_literal_value(*$$, base->name()); + change_string_literal_value(*$$, *new String(base->type())); } else { strcpy(PC.error, "no base class declared"); YYERROR; @@ -1042,13 +1063,12 @@ default: } if(pc.explicit_result && c) switch(c) { + default: + pc.string.append(c); case '\n': case ' ': case '\t': begin=pc.source; begin_pos=pc.pos; - continue; // skip it - default: - result=BAD_NONWHITESPACE_CHARACTER_IN_EXPLICIT_RESULT_MODE; - goto break2; + continue; } break; @@ -1071,8 +1091,8 @@ default: case '"': case '\'': if( - pc.ls == LS_EXPRESSION_STRING_QUOTED && c=='"' || - pc.ls == LS_EXPRESSION_STRING_APOSTROFED && c=='\'') { + (pc.ls == LS_EXPRESSION_STRING_QUOTED && c=='"') || + (pc.ls == LS_EXPRESSION_STRING_APOSTROFED && c=='\'') ) { pop_LS(pc); //"abc". | 'abc'. RC; } @@ -1145,11 +1165,12 @@ default: case LS_METHOD_ROUND: switch(c) { case ')': - if(--lexical_brackets_nestage==0) + if(--lexical_brackets_nestage==0) { if(pc.ls==LS_METHOD_ROUND) // method round param ended pc.ls=LS_METHOD_AFTER; // look for method end else // pc.ls==LS_VAR_ROUND // variable constructor ended pop_LS(pc); // return to normal life + } RC; case '#': // comment start skipping if(end!=begin) { @@ -1574,13 +1595,12 @@ default: } if(pc.explicit_result && c) switch(c) { + default: + pc.string.append(c); case '\n': case ' ': case '\t': begin=pc.source; begin_pos=pc.pos; - continue; // skip it - default: - result=BAD_NONWHITESPACE_CHARACTER_IN_EXPLICIT_RESULT_MODE; - goto break2; + continue; } break;