home *** CD-ROM | disk | FTP | other *** search
/ BURKS 2 / BURKS_AUG97.ISO / BURKS / SOFTWARE / SOURCES / MAWK11AS.ZIP / PARSE.Y (.txt) < prev    next >
Text File  |  1992-01-08  |  35KB  |  1,264 lines

  1.  
  2. /********************************************
  3. parse.y
  4. copyright 1991, Michael D. Brennan
  5.  
  6. This is a source file for mawk, an implementation of
  7. the AWK programming language.
  8.  
  9. Mawk is distributed without warranty under the terms of
  10. the GNU General Public License, version 2, 1991.
  11. ********************************************/
  12.  
  13. /* $Log:    parse.y,v $
  14.  * Revision 5.2  92/01/08  16:11:42  brennan
  15.  * code FE_PUSHA carefully for MSDOS large mode
  16.  * 
  17.  * Revision 5.1  91/12/05  07:50:22  brennan
  18.  * 1.1 pre-release
  19.  * 
  20. */
  21.  
  22.  
  23. %{
  24. #include <stdio.h>
  25. #include "mawk.h"
  26. #include "code.h"
  27. #include "symtype.h"
  28. #include "memory.h"
  29. #include "bi_funct.h"
  30. #include "bi_vars.h"
  31. #include "jmp.h"
  32. #include "field.h"
  33. #include "files.h"
  34.  
  35. #ifdef  YYXBYACC
  36. #define YYBYACC        1
  37. #endif
  38.  
  39. #define  YYMAXDEPTH    200
  40.  
  41. /* Bison's use of MSDOS and ours clashes */
  42. #undef   MSDOS
  43.  
  44. extern void  PROTO( eat_nl, (void) ) ;
  45. static void  PROTO( resize_fblock, (FBLOCK *, INST *) ) ;
  46. static void  PROTO( code_array, (SYMTAB *) ) ;
  47. static void  PROTO( code_call_id, (CA_REC *, SYMTAB *) ) ;
  48. static void  PROTO( field_A2I, (void)) ;
  49. static int   PROTO( current_offset, (void) ) ;
  50. static void  PROTO( check_var, (SYMTAB *) ) ;
  51. static void  PROTO( check_array, (SYMTAB *) ) ;
  52. static void  PROTO( RE_as_arg, (void)) ;
  53.  
  54. static int scope ;
  55. static FBLOCK *active_funct ;
  56.       /* when scope is SCOPE_FUNCT  */
  57.  
  58. #define  code_address(x)  if( is_local(x) )\
  59.                           { code1(L_PUSHA) ; code1((x)->offset) ; }\
  60.                           else  code2(_PUSHA, (x)->stval.cp) 
  61.  
  62. /* this nonsense caters to MSDOS large model */
  63. #define  CODE_FE_PUSHA()  code_ptr->ptr = (PTR) 0 ; code1(FE_PUSHA)
  64.  
  65. %}
  66.  
  67. %union{
  68. CELL *cp ;
  69. SYMTAB *stp ;
  70. INST  *start ; /* code starting address */
  71. PF_CP  fp ;  /* ptr to a (print/printf) or (sub/gsub) function */
  72. BI_REC *bip ; /* ptr to info about a builtin */
  73. FBLOCK  *fbp  ; /* ptr to a function block */
  74. ARG2_REC *arg2p ;
  75. CA_REC   *ca_p  ;
  76. int   ival ;
  77. PTR   ptr ;
  78. }
  79.  
  80. /*  two tokens to help with errors */
  81. %token   UNEXPECTED   /* unexpected character */
  82. %token   BAD_DECIMAL
  83.  
  84. %token   NL
  85. %token   SEMI_COLON
  86. %token   LBRACE  RBRACE
  87. %token   LBOX     RBOX
  88. %token   COMMA
  89. %token   <ival> IO_OUT    /* > or output pipe */
  90.  
  91. %right  ASSIGN  ADD_ASG SUB_ASG MUL_ASG DIV_ASG MOD_ASG POW_ASG
  92. %right  QMARK COLON
  93. %left   OR
  94. %left   AND
  95. %left   IN
  96. %left   <ival> MATCH   /* ~  or !~ */
  97. %left   EQ  NEQ  LT LTE  GT  GTE
  98. %left   CAT
  99. %left   GETLINE
  100. %left   PLUS      MINUS  
  101. %left   MUL      DIV    MOD
  102. %left   NOT   UMINUS
  103. %nonassoc   IO_IN PIPE
  104. %right  POW
  105. %left   <ival>   INC_or_DEC
  106. %left   DOLLAR    FIELD  /* last to remove a SR conflict
  107.                                 with getline */
  108. %right  LPAREN   RPAREN     /* removes some SR conflicts */
  109.  
  110. %token  <ptr> DOUBLE STRING_ RE  
  111. %token  <stp> ID   D_ID
  112. %token  <fbp> FUNCT_ID
  113. %token  <bip> BUILTIN 
  114. %token   <cp>  FIELD 
  115.  
  116. %token  PRINT PRINTF SPLIT MATCH_FUNC SUB GSUB 
  117. /* keywords */
  118. %token  DO WHILE FOR BREAK CONTINUE IF ELSE  IN
  119. %token  DELETE  BEGIN  END  EXIT NEXT RETURN  FUNCTION
  120.  
  121. %type <start>  block  block_or_separator
  122. %type <start>  statement_list statement mark
  123. %type <ival>   pr_args
  124. %type <arg2p>  arg2  
  125. %type <start>  builtin  
  126. %type <start>  getline_file
  127. %type <start>  lvalue field  fvalue
  128. %type <start>  expr cat_expr p_expr
  129. %type <start>  while_front  if_front 
  130. %type <start>  for1 for2
  131. %type <start>  array_loop_front
  132. %type <start>  return_statement
  133. %type <start>  split_front  re_arg sub_back
  134. %type <ival>   arglist args 
  135. %type <fp>     print   sub_or_gsub
  136. %type <fbp>    funct_start funct_head
  137. %type <ca_p>   call_args ca_front ca_back
  138. %type <ival>   f_arglist f_args
  139.  
  140. %%
  141. /*  productions  */
  142.  
  143. program :       program_block
  144.         |       program  program_block 
  145.         ;
  146.  
  147. program_block :  PA_block   /* pattern-action */
  148.               |  function_def
  149.               |  error block
  150.                  { if (scope == SCOPE_FUNCT)
  151.                    { restore_ids() ; scope = SCOPE_MAIN ; }
  152.                    code_ptr = main_code_ptr ;
  153.                  }
  154.               ;
  155.  
  156. PA_block  :  block 
  157.              { /* this do nothing action removes a vacuous warning
  158.                   from Bison */
  159.              }
  160.  
  161.           |  BEGIN  
  162.                 { 
  163.           be_expand(&begin_code) ;
  164.                   scope = SCOPE_BEGIN ;
  165.                 }
  166.  
  167.              block
  168.                 { be_shrink(&begin_code) ;
  169.                   scope = SCOPE_MAIN ;
  170.                 }
  171.  
  172.           |  END    
  173.                 { 
  174.           be_expand(&end_code) ;
  175.                   scope = SCOPE_END ;
  176.                 }
  177.  
  178.              block
  179.                 { be_shrink(&end_code) ;
  180.                   scope = SCOPE_MAIN ;
  181.                 }
  182.  
  183.           |  expr  /* this works just like an if statement */
  184.              { code_jmp(_JZ, (INST*)0) ; }
  185.  
  186.              block_or_separator
  187.              { patch_jmp( code_ptr ) ; }
  188.  
  189.     /* range pattern, see comment in execute.c near _RANGE */
  190.           |  expr COMMA 
  191.              { code_push($1, code_ptr - $1) ;
  192.                code_ptr = $1 ;
  193.                code1(_RANGE) ; code1(1) ;
  194.                code_ptr += 3 ;
  195.                code_ptr += code_pop(code_ptr) ;
  196.                code1(_STOP) ;
  197.                $1[2].op = code_ptr - ($1+1) ;
  198.              }
  199.              expr
  200.              { code1(_STOP) ; }
  201.  
  202.              block_or_separator
  203.              { $1[3].op = $6 - ($1+1) ;
  204.                $1[4].op = code_ptr - ($1+1) ;
  205.              }
  206.           ;
  207.  
  208.  
  209.  
  210. block   :  LBRACE   statement_list  RBRACE
  211.             { $$ = $2 ; }
  212.         |  LBRACE   error  RBRACE 
  213.             { $$ = code_ptr ; /* does nothing won't be executed */
  214.               print_flag = getline_flag = paren_cnt = 0 ;
  215.               yyerrok ; }
  216.         ;
  217.  
  218. block_or_separator  :  block
  219.                   |  separator     /* default print action */
  220.                      { $$ = code_ptr ;
  221.                        code1(_PUSHINT) ; code1(0) ;
  222.                        code2(_PRINT, bi_print) ;
  223.                      }
  224.  
  225. statement_list :  statement
  226.         |  statement_list   statement
  227.         ;
  228.  
  229.  
  230. statement :  block
  231.           |  expr   separator
  232.              { code1(_POP) ; }
  233.           |  /* empty */  separator
  234.              { $$ = code_ptr ; }
  235.           |  error  separator
  236.               { $$ = code_ptr ;
  237.                 print_flag = getline_flag = 0 ;
  238.                 paren_cnt = 0 ;
  239.                 yyerrok ;
  240.               }
  241.           |  BREAK  separator
  242.              { $$ = code_ptr ; BC_insert('B', code_ptr+1) ;
  243.                code2(_JMP, 0) /* don't use code_jmp ! */ ; }
  244.           |  CONTINUE  separator
  245.              { $$ = code_ptr ; BC_insert('C', code_ptr+1) ;
  246.                code2(_JMP, 0) ; }
  247.           |  return_statement
  248.              { if ( scope != SCOPE_FUNCT )
  249.                      compile_error("return outside function body") ;
  250.              }
  251.           |  NEXT  separator
  252.               { if ( scope != SCOPE_MAIN )
  253.                    compile_error( "improper use of next" ) ;
  254.                 $$ = code_ptr ; 
  255.                 code1(_NEXT) ;
  256.               }
  257.           ;
  258.  
  259. separator  :  NL | SEMI_COLON
  260.            ;
  261.  
  262. expr  :   cat_expr
  263.       |   lvalue   ASSIGN   expr { code1(_ASSIGN) ; }
  264.       |   lvalue   ADD_ASG  expr { code1(_ADD_ASG) ; }
  265.       |   lvalue   SUB_ASG  expr { code1(_SUB_ASG) ; }
  266.       |   lvalue   MUL_ASG  expr { code1(_MUL_ASG) ; }
  267.       |   lvalue   DIV_ASG  expr { code1(_DIV_ASG) ; }
  268.       |   lvalue   MOD_ASG  expr { code1(_MOD_ASG) ; }
  269.       |   lvalue   POW_ASG  expr { code1(_POW_ASG) ; }
  270.       |   expr EQ expr  { code1(_EQ) ; }
  271.       |   expr NEQ expr { code1(_NEQ) ; }
  272.       |   expr LT expr { code1(_LT) ; }
  273.       |   expr LTE expr { code1(_LTE) ; }
  274.       |   expr GT expr { code1(_GT) ; }
  275.       |   expr GTE expr { code1(_GTE) ; }
  276.  
  277.       |   expr MATCH expr
  278.           {
  279.             if ( $3 == code_ptr - 2 )
  280.             {
  281.                if ( $3->op == _MATCH0 )  $3->op = _MATCH1 ;
  282.  
  283.                else /* check for string */
  284.                i