Diff for /parser3/src/main/compile.y between versions 1.90 and 1.106.2.1

version 1.90, 2001/03/11 09:30:45 version 1.106.2.1, 2001/03/20 17:52:39
Line 1 Line 1
 /*  /** @file
         Parser          Parser: compiler(lexical parser and grammar).
   
         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$          $Id$
 */  */
   
 /*  /**
         TODO.parser4:           @todo parser4: 
                 cache compiled code from request to request. to do that...          - cache compiled code from request to request. to do that...
                 1:      make method definitions, @CLASS, @BASE, @USE instructions,                  -#:     make method definitions, @CLASS, @BASE, @USE instructions,
                         which would be executed afterwards, and actions                          which would be executed afterwards, and actions
                         now performed at compile time would be delayed to run time.                          now performed at compile time would be delayed to run time.
                 2:      make cache expiration on time and on disk-change of class source                  -#:     make cache expiration on time and on disk-change of class source
                 3:      in apache use subpools for compiled class storage                  -#:     in apache use subpools for compiled class storage
                 4:      in iis make up specialized Pool object for that                  -#:     in iis make up specialized Pool object for that
 */  */
   
 %{  %{
Line 22 Line 24
 #define YYPARSE_PARAM  pc  #define YYPARSE_PARAM  pc
 #define YYLEX_PARAM  pc  #define YYLEX_PARAM  pc
 #define YYDEBUG  1  #define YYDEBUG  1
 #define YYERROR_VERBOSE  #define YYERROR_VERBOSE 1
 #define yyerror(msg)  real_yyerror((parse_control *)pc, msg)  #define yyerror(msg)  real_yyerror((parse_control *)pc, msg)
 #define YYPRINT(file, type, value)  yyprint(file, type, value)  #define YYPRINT(file, type, value)  yyprint(file, type, value)
   
Line 35 Line 37
 #include "pa_request.h"  #include "pa_request.h"
 #include "pa_vobject.h"  #include "pa_vobject.h"
 #include "pa_vdouble.h"  #include "pa_vdouble.h"
 #include "core.h"  #include "pa_globals.h"
   
 #define SELF_ELEMENT_NAME "self"  #define SELF_ELEMENT_NAME "self"
 #define USE_CONTROL_METHOD_NAME "USE"  #define USE_CONTROL_METHOD_NAME "USE"
Line 50  int yylex(YYSTYPE *lvalp, void *pc); Line 52  int yylex(YYSTYPE *lvalp, void *pc);
 #define POOL  *PC->pool  #define POOL  *PC->pool
 #undef NEW  #undef NEW
 #define NEW new(POOL)  #define NEW new(POOL)
   #ifndef DOXYGEN
 %}  %}
   
 %pure_parser  %pure_parser
Line 79  int yylex(YYSTYPE *lvalp, void *pc); Line 82  int yylex(YYSTYPE *lvalp, void *pc);
 %token DEF "def"  %token DEF "def"
 %token IN "in"  %token IN "in"
 %token FEXISTS "-f"  %token FEXISTS "-f"
   %token IS "is"
   
 /* logical */  /* logical */
   %left "is"
 %left "lt" "gt" "le" "ge"  %left "lt" "gt" "le" "ge"
 %left "eq" "ne"  %left "eq" "ne"
 %left '<' '>' "<=" ">=" "##"  %left '<' '>' "<=" ">=" "##"
Line 108  all: Line 113  all:
                 0, 0, /*min, max numbered_params_count*/                  0, 0, /*min, max numbered_params_count*/
                 0/*param_names*/, 0/*local_names*/,                   0/*param_names*/, 0/*local_names*/, 
                 $1/*parser_code*/, 0/*native_code*/);                  $1/*parser_code*/, 0/*native_code*/);
         PC->vclass->add_method(*main_method_name, method);          PC->cclass->add_method(*main_method_name, method);
 }  }
 |       methods;  |       methods;
   
Line 128  control_method: '@' STRING '\n' Line 133  control_method: '@' STRING '\n'
                 YYERROR;                  YYERROR;
         }          }
         if(command==CLASS_NAME) {          if(command==CLASS_NAME) {
                 if(PC->vclass!=&PC->request->root_class) { // already changed from default?                  if(PC->cclass!=&PC->request->ROOT) { // already changed from default?
                         strcpy(PC->error, "class already have a name '");                          strcpy(PC->error, "class already have a name '");
                         strncat(PC->error, PC->vclass->name().cstr(), 100);                          strncat(PC->error, PC->cclass->name().cstr(), 100);
                         strcat(PC->error, "'");                          strcat(PC->error, "'");
                         YYERROR;                          YYERROR;
                 }                  }
Line 138  control_method: '@' STRING '\n' Line 143  control_method: '@' STRING '\n'
                         // new class' name                          // new class' name
                         const String *name=SLA2S(strings_code);                          const String *name=SLA2S(strings_code);
                         // creating the class                          // creating the class
                         PC->vclass=NEW VClass(POOL);                          PC->cclass=NEW VClass(POOL);
                         PC->vclass->set_name(*name);                          PC->cclass->set_name(*name);
                         // defaulting base. may change with @BASE                          // defaulting base. may change with @BASE
                         PC->vclass->set_base(PC->request->root_class);                          PC->cclass->set_base(PC->request->ROOT);
                         // append to request's classes                          // append to request's classes
                         PC->request->classes_array()+=PC->vclass;                          PC->request->classes().put(*name, PC->cclass);
                         PC->request->classes().put(*name, PC->vclass);  
                 } else {                  } else {
                         strcpy(PC->error, "@"CLASS_NAME" must contain sole name");                          strcpy(PC->error, "@"CLASS_NAME" must contain sole name");
                         YYERROR;                          YYERROR;
Line 154  control_method: '@' STRING '\n' Line 158  control_method: '@' STRING '\n'
                         for(int i=0; i<strings_code->size(); i+=2) {                          for(int i=0; i<strings_code->size(); i+=2) {
                                 String file(*SLA2S(strings_code, i));                                  String file(*SLA2S(strings_code, i));
                                 file.APPEND_CONST(".p");                                  file.APPEND_CONST(".p");
                                 PC->request->use(file.cstr());                                  PC->request->use_file(file.cstr());
                         }                          }
                 } else if(command==BASE_NAME) {                  } else if(command==BASE_NAME) {
                         if(PC->vclass->base()!=&PC->request->root_class) { // already changed from default?                          if(PC->cclass->base()!=&PC->request->ROOT) { // already changed from default?
                                 strcpy(PC->error, "class already have a base '");                                  strcpy(PC->error, "class already have a base '");
                                 strncat(PC->error, PC->vclass->base()->name().cstr(), 100);                                  strncat(PC->error, PC->cclass->base()->name().cstr(), 100);
                                 strcat(PC->error, "'");                                  strcat(PC->error, "'");
                                 YYERROR;                                  YYERROR;
                         }                          }
Line 173  control_method: '@' STRING '\n' Line 177  control_method: '@' STRING '\n'
                                         strcat(PC->error, ": undefined class in @"BASE_NAME);                                          strcat(PC->error, ": undefined class in @"BASE_NAME);
                                         YYERROR;                                          YYERROR;
                                 }                                  }
                                 PC->vclass->set_base(*base);                                  PC->cclass->set_base(*base);
                         } else {                          } else {
                                 strcpy(PC->error, "@"BASE_NAME" must contain sole name");                                  strcpy(PC->error, "@"BASE_NAME" must contain sole name");
                                 YYERROR;                                  YYERROR;
                         }                          }
                 } else {                  } else {
                         strcpy(PC->error, command.cstr());                          strcpy(PC->error, "'");
                         strcat(PC->error, ": invalid special name. valid names are "                          strncat(PC->error, command.cstr(), MAX_STRING/2);
                                 CLASS_NAME", "USE_CONTROL_METHOD_NAME" and "BASE_NAME);                          strcat(PC->error, "' invalid special name. valid names are "
                                   "'"CLASS_NAME"', '"USE_CONTROL_METHOD_NAME"' and '"BASE_NAME"'");
                         YYERROR;                          YYERROR;
                 }                  }
         }          }
Line 215  code_method: '@' STRING bracketed_maybe_ Line 220  code_method: '@' STRING bracketed_maybe_
                 0, 0/*min,max numbered_params_count*/,                   0, 0/*min,max numbered_params_count*/, 
                 params_names, locals_names,                   params_names, locals_names, 
                 $7, 0);                  $7, 0);
         PC->vclass->add_method(*name, method);          PC->cclass->add_method(*name, method);
 };  };
   
 maybe_bracketed_strings: empty | bracketed_maybe_strings;  maybe_bracketed_strings: empty | bracketed_maybe_strings;
Line 237  action: get | put | with | call; Line 242  action: get | put | with | call;
   
 get: get_value {  get: get_value {
         $$=$1; /* stack: resulting value */          $$=$1; /* stack: resulting value */
         O($$, OP_WRITE); /* value=pop; wcontext.write(value) */          O($$, OP_WRITE_VALUE); /* value=pop; wcontext.write(value) */
 };  };
 get_value: '$' get_name_value { $$=$2 }  get_value: '$' get_name_value { $$=$2 }
 get_name_value: name_without_curly_rdive EON | name_in_curly_rdive;  get_name_value: name_without_curly_rdive EON | name_in_curly_rdive;
Line 330  codes__excluding_sole_str_literal: actio Line 335  codes__excluding_sole_str_literal: actio
   
 call: call_value {  call: call_value {
         $$=$1; /* stack: value */          $$=$1; /* stack: value */
         O($$, OP_WRITE); /* 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: '^' call_name store_params EON { /* ^field.$method{vasya} */
         $$=$2; /* with_xxx,diving code; stack: context,method_junction */          $$=$2; /* with_xxx,diving code; stack: context,method_junction */
Line 349  store_param: Line 354  store_param:
 ;  ;
 store_square_param: '[' store_code_param_parts ']' {$$=$2};  store_square_param: '[' store_code_param_parts ']' {$$=$2};
 store_round_param: '(' store_expr_param_parts ')' {$$=$2};  store_round_param: '(' store_expr_param_parts ')' {$$=$2};
 store_curly_param: '{' maybe_codes '}' {  store_curly_param: '{' store_curly_param_parts '}' {$$=$2};
         $$=N(POOL);   
         PCA($$, $2);  
 };  
 store_code_param_parts:  store_code_param_parts:
         store_code_param_part          store_code_param_part
 |       store_code_param_parts ';' store_code_param_part { $$=$1; P($$, $3) }  |       store_code_param_parts ';' store_code_param_part { $$=$1; P($$, $3) }
Line 361  store_expr_param_parts: Line 363  store_expr_param_parts:
         store_expr_param_part          store_expr_param_part
 |       store_expr_param_parts ';' store_expr_param_part { $$=$1; P($$, $3) }  |       store_expr_param_parts ';' store_expr_param_part { $$=$1; P($$, $3) }
 ;  ;
   store_curly_param_parts:
           store_curly_param_part
   |       store_curly_param_parts ';' store_curly_param_part { $$=$1; P($$, $3) }
   ;
 store_code_param_part:   store_code_param_part: 
         empty /* optimized [] case */          empty /* optimized [] case */
 |       STRING { /* optimized [STRING] case */  |       STRING { /* optimized [STRING] case */
Line 374  store_code_param_part: Line 380  store_code_param_part:
 ;  ;
 store_expr_param_part: write_expr_value {  store_expr_param_part: write_expr_value {
         $$=N(POOL);           $$=N(POOL); 
           PEA($$, $1);
   };
   store_curly_param_part: maybe_codes {
           $$=N(POOL); 
         PCA($$, $1);          PCA($$, $1);
 };  };
 write_expr_value: expr_value {  write_expr_value: expr_value {
         $$=$1;          $$=$1;
         O($$, OP_WRITE);          O($$, OP_WRITE_EXPR_RESULT);
 };  };
   
 /* name */  /* name */
Line 412  name_expr_with_subvar_value: STRING subv Line 422  name_expr_with_subvar_value: STRING subv
         $$=N(POOL);           $$=N(POOL); 
         O($$, OP_CREATE_EWPOOL);          O($$, OP_CREATE_EWPOOL);
         P($$, $1);          P($$, $1);
         O($$, OP_WRITE);          O($$, OP_WRITE_VALUE);
         P($$, $2);          P($$, $2);
         O($$, OP_REDUCE_EWPOOL);          O($$, OP_REDUCE_EWPOOL);
 };  };
Line 446  with: '$' name_without_curly_rdive '{' c Line 456  with: '$' name_without_curly_rdive '{' c
         O($$, OP_CREATE_RWPOOL);          O($$, OP_CREATE_RWPOOL);
         P($$, $4);          P($$, $4);
         O($$, OP_REDUCE_RWPOOL);          O($$, OP_REDUCE_RWPOOL);
         O($$, OP_WRITE);          O($$, OP_WRITE_VALUE);
 };  };
   
 /* expr */  /* expr */
Line 492  expr: Line 502  expr:
 |       expr "ge" expr { $$=$1;  P($$, $3);  O($$, OP_STR_GE) }  |       expr "ge" expr { $$=$1;  P($$, $3);  O($$, OP_STR_GE) }
 |       expr "eq" expr { $$=$1;  P($$, $3);  O($$, OP_STR_EQ) }  |       expr "eq" expr { $$=$1;  P($$, $3);  O($$, OP_STR_EQ) }
 |       expr "ne" expr { $$=$1;  P($$, $3);  O($$, OP_STR_NE) }  |       expr "ne" expr { $$=$1;  P($$, $3);  O($$, OP_STR_NE) }
   |       expr "is" expr { $$=$1;  P($$, $3);  O($$, OP_IS) }
 ;  ;
   
 string_inside_quotes_value: maybe_codes {  string_inside_quotes_value: maybe_codes {
Line 504  string_inside_quotes_value: maybe_codes Line 515  string_inside_quotes_value: maybe_codes
 /* basics */  /* basics */
   
 write_string: STRING {  write_string: STRING {
         // optimized from OP_STRING+OP_WRITE to OP_STRING__WRITE          // optimized from OP_STRING+OP_WRITE_VALUE to OP_STRING__WRITE
         change_string_literal_to_write_string_literal($$=$1)          change_string_literal_to_write_string_literal($$=$1)
 };  };
   
Line 512  empty_string_value: /* empty */ { $$=VL( Line 523  empty_string_value: /* empty */ { $$=VL(
 empty: /* empty */ { $$=N(POOL) };  empty: /* empty */ { $$=N(POOL) };
   
 %%  %%
   #endif
   
 /*  /*
         000$111(2222)00           000$111(2222)00 
Line 542  int yylex(YYSTYPE *lvalp, void *pc) { Line 554  int yylex(YYSTYPE *lvalp, void *pc) {
                 return result;                  return result;
         }          }
                   
         char *begin=PC->source;          const char *begin=PC->source;
         char *end;          const char *end;
         int begin_line=PC->line;          int begin_line=PC->line;
         int skip_analized=0;          int skip_analized=0;
         while(true) {          while(true) {
Line 741  int yylex(YYSTYPE *lvalp, void *pc) { Line 753  int yylex(YYSTYPE *lvalp, void *pc) {
                                 break;                                  break;
                         case 'i':                          case 'i':
                                 if(end==begin) // right after whitespace                                  if(end==begin) // right after whitespace
                                         if(PC->source[0]=='n') { // in                                          switch(PC->source[0]) {
                                                 skip_analized=1;                                          case 'n': 
                                                 result=IN;                                                  { // in
                                                 goto break2;                                                          skip_analized=1;
                                                           result=IN;
                                                           goto break2;
                                                   }
                                           case 's': 
                                                   { // is
                                                           skip_analized=1;
                                                           result=IS;
                                                           goto break2;
                                                   }
                                         }                                          }
                                 break;                                  break;
                         case 'd':                          case 'd':
Line 775  int yylex(YYSTYPE *lvalp, void *pc) { Line 796  int yylex(YYSTYPE *lvalp, void *pc) {
                         if(PC->ls==LS_EXPRESSION_VAR_NAME) {                          if(PC->ls==LS_EXPRESSION_VAR_NAME) {
                                 // name in expr ends also before binary operators                                   // name in expr ends also before binary operators 
                                 switch(c) {                                  switch(c) {
                                 case '+': case '-': case '*': case '/': case '%':                                   case '-': 
                                 case '&': case '|':   
                                 case '=': case '!':  
                                         pop_LS(PC);                                          pop_LS(PC);
                                         PC->source--;  if(--PC->col<0) { PC->line--;  PC->col=-1; }                                          PC->source--;  if(--PC->col<0) { PC->line--;  PC->col=-1; }
                                         result=EON;                                          result=EON;
Line 790  int yylex(YYSTYPE *lvalp, void *pc) { Line 809  int yylex(YYSTYPE *lvalp, void *pc) {
                         case ';':                          case ';':
                         case ']': case '}': case ')': case '"':                          case ']': case '}': case ')': case '"':
                         case '<': case '>':  // these stand for HTML brackets and expression binary ops                          case '<': case '>':  // these stand for HTML brackets and expression binary ops
                           case '+': case '*': case '/': case '%': 
                           case '&': case '|': 
                           case '=': case '!':
                           // common delimiters
                           case '\'': case ',':
                                 pop_LS(PC);                                  pop_LS(PC);
                                 PC->source--;  if(--PC->col<0) { PC->line--;  PC->col=-1; }                                  PC->source--;  if(--PC->col<0) { PC->line--;  PC->col=-1; }
                                 result=EON;                                  result=EON;
Line 924  int yylex(YYSTYPE *lvalp, void *pc) { Line 948  int yylex(YYSTYPE *lvalp, void *pc) {
                         case '^':                          case '^':
                                 push_LS(PC, LS_METHOD_NAME);                                  push_LS(PC, LS_METHOD_NAME);
                                 RC;                                  RC;
                           case ';': // param delim
                                   RC;
                         case '}':                          case '}':
                                 if(--lexical_brackets_nestage==0) {                                  if(--lexical_brackets_nestage==0) {
                                         PC->ls=LS_METHOD_AFTER;                                          PC->ls=LS_METHOD_AFTER;
Line 990  break2: Line 1016  break2:
   
 int real_yyerror(parse_control *pc, char *s)  /* Called by yyparse on error */  int real_yyerror(parse_control *pc, char *s)  /* Called by yyparse on error */
      {       {
        //fprintf(stderr, "[%s]\n", s);  
   
            strncpy(pc->error, s, MAX_STRING); // TODO: перепроверить с треклятым последним байтом             strncpy(pc->error, s, MAX_STRING); // TODO: перепроверить с треклятым последним байтом
            return 1;             return 1;
      }       }

Removed from v.1.90  
changed lines
  Added in v.1.106.2.1


E-mail: