Diff for /parser3/src/main/compile.y between versions 1.142 and 1.156

version 1.142, 2001/06/28 07:33:38 version 1.156, 2001/07/26 14:15:45
Line 4 Line 4
         Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
   
         Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)          Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
   
         $Id$  
 */  */
   %{
   static char *RCSId="$Id$"; 
   
 /**  /**
         @todo parser4:           @todo parser4: 
Line 19 Line 19
                 -#:     in iis make up specialized Pool object for that                  -#:     in iis make up specialized Pool object for that
 */  */
   
 %{  
 #define YYSTYPE  Array/*<Operation>*/ *  #define YYSTYPE  Array/*<Operation>*/ *
 #define YYPARSE_PARAM  pc  #define YYPARSE_PARAM  pc
 #define YYLEX_PARAM  pc  #define YYLEX_PARAM  pc
Line 38 Line 37
   
 #define SELF_ELEMENT_NAME "self"  #define SELF_ELEMENT_NAME "self"
 #define USE_CONTROL_METHOD_NAME "USE"  #define USE_CONTROL_METHOD_NAME "USE"
 #define END_CONTROL_METHOD_NAME "end"  
   
 static int real_yyerror(parse_control *pc, char *s);  static int real_yyerror(parse_control *pc, char *s);
 static void yyprint(FILE *file, int type, YYSTYPE value);  static void yyprint(FILE *file, int type, YYSTYPE value);
Line 105  static int yylex(YYSTYPE *lvalp, void *p Line 103  static int yylex(YYSTYPE *lvalp, void *p
 %left NEG     /* negation: unary - */  %left NEG     /* negation: unary - */
   
 %%  %%
 all:  all: 
         one_big_piece {          one_big_piece {
         Method& method=*NEW Method(POOL,           Method& method=*NEW Method(POOL, 
                 *main_method_name,                   *main_method_name, 
Line 126  control_method: '@' STRING '\n' Line 124  control_method: '@' STRING '\n'
                                 maybe_control_strings {                                  maybe_control_strings {
         const String& command=*LA2S($2);          const String& command=*LA2S($2);
         YYSTYPE strings_code=$4;          YYSTYPE strings_code=$4;
         if(command==END_CONTROL_METHOD_NAME && strings_code->size()==0)  
                 break;  
         if(strings_code->size()<1*2) {          if(strings_code->size()<1*2) {
                 strcpy(PC.error, "@");                  strcpy(PC.error, "@");
                 strcat(PC.error, command.cstr());                  strcat(PC.error, command.cstr());
Line 135  control_method: '@' STRING '\n' Line 131  control_method: '@' STRING '\n'
                 YYERROR;                  YYERROR;
         }          }
         if(command==CLASS_NAME) {          if(command==CLASS_NAME) {
                 if(PC.cclass) { // already changed from default?                  if(PC.cclass->base()) { // already changed from default?
                         strcpy(PC.error, "class already have a name '");                          strcpy(PC.error, "class already have a name '");
                         strncat(PC.error, PC.cclass->name().cstr(), 100);                          strncat(PC.error, PC.cclass->name().cstr(), 100);
                         strcat(PC.error, "'");                          strcat(PC.error, "'");
Line 158  control_method: '@' STRING '\n' Line 154  control_method: '@' STRING '\n'
                         PC.request->use_file(                          PC.request->use_file(
                         PC.request->absolute(*LA2S(strings_code, i)));                          PC.request->absolute(*LA2S(strings_code, i)));
         } else if(command==BASE_NAME) {          } else if(command==BASE_NAME) {
                 if(PC.cclass->base()!=&PC.request->OP) { // already changed from default?                  if(PC.cclass->base()) { // already changed from default?
                         strcpy(PC.error, "class already have a base '");                          strcpy(PC.error, "class already have a base '");
                         strncat(PC.error, PC.cclass->base()->name().cstr(), 100);                          strncat(PC.error, PC.cclass->base()->name().cstr(), 100);
                         strcat(PC.error, "'");                          strcat(PC.error, "'");
Line 238  maybe_codes: empty | codes; Line 234  maybe_codes: empty | codes;
   
 codes: code | codes code { $$=$1; P($$, $2) };  codes: code | codes code { $$=$1; P($$, $2) };
 code: write_string | action;  code: write_string | action;
 action: get | put | with | call;  action: get | put | call;
   
 /* get */  /* get */
   
Line 251  get_name_value: name_without_curly_rdive Line 247  get_name_value: name_without_curly_rdive
 name_in_curly_rdive: '{' name_without_curly_rdive '}' { $$=$2 };  name_in_curly_rdive: '{' name_without_curly_rdive '}' { $$=$2 };
 name_without_curly_rdive:   name_without_curly_rdive: 
         name_without_curly_rdive_read           name_without_curly_rdive_read 
 |       name_without_curly_rdive_root  
 |       name_without_curly_rdive_class;  |       name_without_curly_rdive_class;
 name_without_curly_rdive_read: name_without_curly_rdive_code {  name_without_curly_rdive_read: name_without_curly_rdive_code {
         $$=N(POOL);           $$=N(POOL); 
Line 268  name_without_curly_rdive_read: name_with Line 263  name_without_curly_rdive_read: name_with
         }          }
         /* diving code; stack: current context */          /* diving code; stack: current context */
 };  };
 name_without_curly_rdive_root: ':' name_without_curly_rdive_code {  
         $$=N(POOL);   
         O($$, 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_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) };  name_without_curly_rdive_code: name_advance2 | name_path name_advance2 { $$=$1; P($$, $2) };
   
Line 308  name_expr_wdive_root: ':' name_expr_dive Line 298  name_expr_wdive_root: ':' name_expr_dive
 };  };
 name_expr_wdive_class: class_prefix name_expr_dive_code { $$=$1; P($$, $2) };  name_expr_wdive_class: class_prefix name_expr_dive_code { $$=$1; P($$, $2) };
   
 construct: construct_by_code | construct_by_expr;  construct: 
 construct_by_code: '[' any_constructor_code_value ']' {          construct_square | 
         $$=$2; /* stack: context, name, value */          construct_round |
           construct_curly
   ;
   construct_square: '[' any_constructor_code_value ']' {
           // stack: context, name
           $$=$2; // stack: context, name, value
         O($$, OP_CONSTRUCT_VALUE); /* value=pop; name=pop; context=pop; construct(context,name,value) */          O($$, OP_CONSTRUCT_VALUE); /* value=pop; name=pop; context=pop; construct(context,name,value) */
 }  }
 ;  ;
 construct_by_expr: '(' expr_value ')' {   construct_round: '(' expr_value ')' { 
         $$=$2; /* stack: context, name, value */          // stack: context, name
           $$=$2; // stack: context, name, value
         O($$, OP_CONSTRUCT_EXPR); /* value=pop; name=pop; context=pop; construct(context,name,value) */          O($$, OP_CONSTRUCT_EXPR); /* value=pop; name=pop; context=pop; construct(context,name,value) */
 }  }
 ;  ;
   construct_curly: '{' maybe_codes '}' {
           // stack: context, name
           $$=N(POOL); 
           CCA($$, $2); /* code=pop; name=pop; context=pop; construct(context,name,junction(code)) */
   };
   
 any_constructor_code_value:   any_constructor_code_value: 
         unknown_value /* optimized $var[] case */          empty_string_value /* optimized $var[] case */
 |       STRING /* optimized $var[STRING] case */  |       STRING /* optimized $var[STRING] case */
 |       constructor_code_value /* $var[something complex] */  |       constructor_code_value /* $var[something complex] */
 ;  ;
Line 339  call: call_value { Line 341  call: call_value {
         $$=$1; /* stack: value */          $$=$1; /* stack: value */
         O($$, OP_WRITE_VALUE); /* value=pop; wcontext.write(value) */          O($$, OP_WRITE_VALUE); /* value=pop; wcontext.write(value) */
 };  };
 call_value: '^' call_name store_params EON { /* ^field.$method{vasya} */  call_value: '^' { PC.object_constructor_allowed=true } 
         $$=$2; /* with_xxx,diving code; stack: context,method_junction */                          call_name { PC.object_constructor_allowed=false } 
                           store_params EON { /* ^field.$method{vasya} */
           $$=$3; /* with_xxx,diving code; stack: context,method_junction */
         O($$, OP_GET_METHOD_FRAME); /* stack: context,method_frame */          O($$, OP_GET_METHOD_FRAME); /* stack: context,method_frame */
   
         YYSTYPE params_code=$3;          YYSTYPE params_code=$5;
         if(params_code->size()==3) // probably [] case. [OP_VALUE + Void + STORE_PARAM]          if(params_code->size()==3) // probably [] case. [OP_VALUE + Void + STORE_PARAM]
                 if(Value *value=LA2V(params_code)) // it is OP_VALUE + value?                  if(Value *value=LA2V(params_code)) // it is OP_VALUE + value?
                         if(!value->is_defined()) // value is VVoid?                          if(!value->is_defined()) // value is VVoid?
Line 389  store_curly_param_part: maybe_codes { Line 393  store_curly_param_part: maybe_codes {
         PCA($$, $1);          PCA($$, $1);
 };  };
 code_param_value:  code_param_value:
         unknown_value /* optimized [;...] case */          empty_void_value /* optimized [;...] case */
 |       STRING /* optimized [STRING] case */  |       STRING /* optimized [STRING] case */
 |       constructor_code_value /* [something complex] */  |       constructor_code_value /* [something complex] */
 ;  ;
Line 433  name_expr_with_subvar_value: STRING subv Line 437  name_expr_with_subvar_value: STRING subv
         P($$, $2);          P($$, $2);
         O($$, OP_REDUCE_EWPOOL);          O($$, OP_REDUCE_EWPOOL);
 };  };
 subvar_ref_name_rdive: subvar_ref_name_rdive_read | subvar_ref_name_rdive_root;  subvar_ref_name_rdive: STRING {
 subvar_ref_name_rdive_read: STRING {  
         $$=N(POOL);           $$=N(POOL); 
         O($$, OP_WITH_READ);          O($$, OP_WITH_READ);
         P($$, $1);          P($$, $1);
 };  };
 subvar_ref_name_rdive_root: ':' STRING {  
         $$=N(POOL);   
         O($$, OP_WITH_ROOT);  
         P($$, $2);  
 };  
 subvar_get_writes: subvar__get_write | subvar_get_writes subvar__get_write { $$=$1; P($$, $2) };  subvar_get_writes: subvar__get_write | subvar_get_writes subvar__get_write { $$=$1; P($$, $2) };
 subvar__get_write: '$' subvar_ref_name_rdive {  subvar__get_write: '$' subvar_ref_name_rdive {
         $$=$2;          $$=$2;
         O($$, OP_GET_ELEMENT__WRITE);          O($$, OP_GET_ELEMENT__WRITE);
 };  };
   
 class_prefix: STRING ':' {  class_prefix:
           class_static_prefix
   |       class_constructor_prefix
   ;
   class_static_prefix: STRING ':' {
         $$=$1; // stack: class name string          $$=$1; // stack: class name string
         O($$, OP_GET_CLASS);          O($$, OP_GET_CLASS);
 };  };
   class_constructor_prefix: class_static_prefix ':' {
           $$=$1;
 /* with */          if(!PC.object_constructor_allowed) {
                   strcpy(PC.error, ":: not allowed here");
 with: '$' name_without_curly_rdive '{' maybe_codes '}' {                  YYERROR;
         $$=$2;          }
         O($$, OP_CREATE_RWPOOL);          O($$, OP_PREPARE_TO_CONSTRUCT_OBJECT);
         P($$, $4);  
         O($$, OP_REDUCE_RWPOOL);  
         O($$, OP_WRITE_VALUE);  
 };  };
   
   
 /* expr */  /* expr */
   
 expr_value: expr {  expr_value: expr {
Line 477  expr: Line 477  expr:
 |       get_value  |       get_value
 |       call_value  |       call_value
 |       '"' string_inside_quotes_value '"' { $$ = $2; }  |       '"' string_inside_quotes_value '"' { $$ = $2; }
   |       '\'' string_inside_quotes_value '\'' { $$ = $2; }
 |       '(' expr ')' { $$ = $2; }  |       '(' expr ')' { $$ = $2; }
 /* stack: operand // stack: @operand */  /* stack: operand // stack: @operand */
 |       '-' expr %prec NEG { $$=$2;  O($$, OP_NEG) }  |       '-' expr %prec NEG { $$=$2;  O($$, OP_NEG) }
Line 527  write_string: STRING { Line 528  write_string: STRING {
         change_string_literal_to_write_string_literal($$=$1)          change_string_literal_to_write_string_literal($$=$1)
 };  };
   
 unknown_value: /* empty */ { $$=VL(NEW VVoid(POOL)) };  empty_void_value: /* empty */ { $$=VL(NEW VVoid(POOL)) };
   empty_string_value: /* empty */ { $$=VL(NEW VString(POOL)) };
 empty: /* empty */ { $$=N(POOL) };  empty: /* empty */ { $$=N(POOL) };
   
 %%  %%
Line 636  static int yylex(YYSTYPE *lvalp, void *p Line 638  static int yylex(YYSTYPE *lvalp, void *p
   
                 // USER'S = NOT OURS                  // USER'S = NOT OURS
                 case LS_USER:                  case LS_USER:
                           if(PC.trim_bof)
                                   switch(c) {
                                   case '\n': case ' ': case '\t':
                                           begin=PC.source;
                                           begin_line=PC.line;
                                           continue; // skip it
                                   default:
                                           PC.trim_bof=false;
                                   }
                         switch(c) {                          switch(c) {
                         case '$':                          case '$':
                                 push_LS(PC, LS_VAR_NAME_SIMPLE);                                  push_LS(PC, LS_VAR_NAME_SIMPLE);
Line 665  static int yylex(YYSTYPE *lvalp, void *p Line 676  static int yylex(YYSTYPE *lvalp, void *p
                         break;                          break;
                                                   
                 // STRING IN EXPRESSION                  // STRING IN EXPRESSION
                 case LS_EXPRESSION_STRING:                  case LS_EXPRESSION_STRING_QUOTED:
                   case LS_EXPRESSION_STRING_APOSTROFED:
                         switch(c) {                          switch(c) {
                         case '"':                          case '"':
                                 pop_LS(PC); //"abc".                          case '\'':
                                 RC;                                  if(
                                           PC.ls == LS_EXPRESSION_STRING_QUOTED && c=='"' ||
                                           PC.ls == LS_EXPRESSION_STRING_APOSTROFED && c=='\'') {
                                           pop_LS(PC); //"abc". | 'abc'.
                                           RC;
                                   }
                                   break;
                         case '$':                          case '$':
                                 push_LS(PC, LS_VAR_NAME_SIMPLE);                                  push_LS(PC, LS_VAR_NAME_SIMPLE);
                                 RC;                                  RC;
Line 726  static int yylex(YYSTYPE *lvalp, void *p Line 744  static int yylex(YYSTYPE *lvalp, void *p
                         break;                          break;
   
                 case LS_DEF_SPECIAL_BODY:                  case LS_DEF_SPECIAL_BODY:
                           //                          @todo in case
                           // ################
                           // @next-method
                           // we are here with c=='@'
                           // which is wrong, and need action
                         if(c=='\n') {                          if(c=='\n') {
                                 switch(*PC.source) {                                  switch(*PC.source) {
                                 case '@': case 0: // end of special_code                                  case '@': case 0: // end of special_code
Line 795  static int yylex(YYSTYPE *lvalp, void *p Line 818  static int yylex(YYSTYPE *lvalp, void *p
                                         result=c;                                          result=c;
                                 goto break2;                                  goto break2;
                         case '"':                          case '"':
                                 push_LS(PC, LS_EXPRESSION_STRING);                                  push_LS(PC, LS_EXPRESSION_STRING_QUOTED);
                                   RC;
                           case '\'':
                                   push_LS(PC, LS_EXPRESSION_STRING_APOSTROFED);
                                 RC;                                  RC;
                         case 'l': case 'g': case 'e': case 'n':                          case 'l': case 'g': case 'e': case 'n':
                                 if(end==begin) // right after whitespace                                  if(end==begin) // right after whitespace

Removed from v.1.142  
changed lines
  Added in v.1.156


E-mail: