"Fossies" - the Fresh Open Source Software Archive

Member "bc-1.06.95/bc/sbc.y" (27 May 2005, 11178 Bytes) of package /linux/misc/old/bc-1.06.95.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Bison source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "sbc.y": 1.06.95_vs_1.07.

    1 %{
    2 /* sbc.y: A POSIX bc processor written for minix with no extensions.  */
    3  
    4 /*  This file is part of GNU bc.
    5     Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
    6 
    7     This program is free software; you can redistribute it and/or modify
    8     it under the terms of the GNU General Public License as published by
    9     the Free Software Foundation; either version 2 of the License , or
   10     (at your option) any later version.
   11 
   12     This program is distributed in the hope that it will be useful,
   13     but WITHOUT ANY WARRANTY; without even the implied warranty of
   14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15     GNU General Public License for more details.
   16 
   17     You should have received a copy of the GNU General Public License
   18     along with this program; see the file COPYING.  If not, write to
   19       The Free Software Foundation, Inc.
   20       51 Franklin Street, Fifth Floor
   21       Boston, MA 02110-1301  USA
   22 
   23 
   24     You may contact the author by:
   25        e-mail:  philnelson@acm.org
   26       us-mail:  Philip A. Nelson
   27                 Computer Science Department, 9062
   28                 Western Washington University
   29                 Bellingham, WA 98226-9062
   30        
   31 *************************************************************************/
   32 
   33 #include "bcdefs.h"
   34 #include "global.h"     /* To get the global variables. */
   35 #include "proto.h"
   36 %}
   37 
   38 %start program
   39 
   40 %union {
   41     char *s_value;
   42     char  c_value;
   43     int   i_value;
   44     arg_list *a_value;
   45        }
   46 
   47 %token <i_value> ENDOFLINE AND OR NOT
   48 %token <s_value> STRING NAME NUMBER
   49 /*     '-', '+' are tokens themselves       */
   50 %token <c_value> ASSIGN_OP
   51 /*     '=', '+=',  '-=', '*=', '/=', '%=', '^=' */
   52 %token <s_value> REL_OP
   53 /*     '==', '<=', '>=', '!=', '<', '>'     */
   54 %token <c_value> INCR_DECR
   55 /*     '++', '--'               */
   56 %token <i_value> Define    Break    Quit    Length
   57 /*     'define', 'break', 'quit', 'length'  */
   58 %token <i_value> Return    For    If    While    Sqrt  Else
   59 /*     'return', 'for', 'if', 'while', 'sqrt',  'else'  */
   60 %token <i_value> Scale    Ibase    Obase    Auto  Read
   61 /*     'scale', 'ibase', 'obase', 'auto', 'read'    */
   62 %token <i_value> Warranty, Halt, Last, Continue, Print, Limits
   63 /*     'warranty', 'halt', 'last', 'continue', 'print', 'limits'  */
   64 
   65 /* The types of all other non-terminals. */
   66 %type <i_value> expression named_expression return_expression
   67 %type <a_value> opt_parameter_list parameter_list opt_auto_define_list
   68 %type <a_value> define_list opt_argument_list argument_list
   69 %type <i_value> program input_item semicolon_list statement_list
   70 %type <i_value> statement_or_error statement function relational_expression 
   71 
   72 /* precedence */
   73 %nonassoc REL_OP
   74 %right ASSIGN_OP
   75 %left '+' '-'
   76 %left '*' '/' '%'
   77 %right '^'
   78 %nonassoc UNARY_MINUS
   79 %nonassoc INCR_DECR
   80 
   81 %%
   82 program         : /* empty */
   83                 {
   84                   $$ = 0;
   85                   std_only = TRUE;
   86                   if (interactive && !quiet)
   87                 {
   88                   show_bc_version ();
   89                   welcome ();
   90                 }
   91                 }
   92             | program input_item
   93             ;
   94 input_item      : semicolon_list ENDOFLINE
   95                 { run_code (); }
   96             | function
   97                 { run_code (); }
   98             | error ENDOFLINE
   99                 {
  100                   yyerrok; 
  101                   init_gen () ;
  102                 }
  103             ;
  104 semicolon_list      : /* empty */
  105                 { $$ = 0; }
  106             | statement_or_error
  107             | semicolon_list ';' statement_or_error
  108             | semicolon_list ';'
  109             ;
  110 statement_list      : /* empty */
  111                 { $$ = 0; }
  112             | statement
  113             | statement_list ENDOFLINE
  114             | statement_list ENDOFLINE statement
  115             | statement_list ';'
  116             | statement_list ';' statement
  117             ;
  118 statement_or_error  : statement
  119             | error statement
  120                 { $$ = $2; }
  121             ;
  122 statement       : Warranty
  123                 { warranty ("s"); }
  124             | expression
  125                 {
  126                   if ($1 & 1)
  127                 generate ("W");
  128                   else
  129                 generate ("p");
  130                 }
  131             | STRING
  132                 {
  133                   $$ = 0;
  134                   generate ("w");
  135                   generate ($1);
  136                   free ($1);
  137                 }
  138             | Break
  139                 {
  140                   if (break_label == 0)
  141                 yyerror ("Break outside a for/while");
  142                   else
  143                 {
  144                   sprintf (genstr, "J%1d:", break_label);
  145                   generate (genstr);
  146                 }
  147                 }
  148             | Quit
  149                 { exit (0); }
  150             | Return
  151                 { generate ("0R"); }
  152             | Return '(' return_expression ')'
  153                 { generate ("R"); }
  154             | For 
  155                 {
  156                   $1 = break_label; 
  157                   break_label = next_label++;
  158                 }
  159               '(' expression ';'
  160                 {
  161                   $4 = next_label++;
  162                   sprintf (genstr, "pN%1d:", $4);
  163                   generate (genstr);
  164                 }
  165               relational_expression ';'
  166                 {
  167                   $7 = next_label++;
  168                   sprintf (genstr, "B%1d:J%1d:", $7, break_label);
  169                   generate (genstr);
  170                   $<i_value>$ = next_label++;
  171                   sprintf (genstr, "N%1d:", $<i_value>$);
  172                   generate (genstr);
  173                 }
  174               expression ')'
  175                 {
  176                   sprintf (genstr, "pJ%1d:N%1d:", $4, $7);
  177                   generate (genstr);
  178                 }
  179               statement
  180                 {
  181                   sprintf (genstr, "J%1d:N%1d:", $<i_value>9,
  182                        break_label);
  183                   generate (genstr);
  184                   break_label = $1;
  185                 }
  186             | If '(' relational_expression ')' 
  187                 {
  188                   $3 = next_label++;
  189                   sprintf (genstr, "Z%1d:", $3);
  190                   generate (genstr);
  191                 }
  192               statement
  193                 {
  194                   sprintf (genstr, "N%1d:", $3); 
  195                   generate (genstr);
  196                 }
  197             | While 
  198                 {
  199                   $1 = next_label++;
  200                   sprintf (genstr, "N%1d:", $1);
  201                   generate (genstr);
  202                 }
  203             '(' relational_expression 
  204                 {
  205                   $4 = break_label; 
  206                   break_label = next_label++;
  207                   sprintf (genstr, "Z%1d:", break_label);
  208                   generate (genstr);
  209                 }
  210             ')' statement
  211                 {
  212                   sprintf (genstr, "J%1d:N%1d:", $1, break_label);
  213                   generate (genstr);
  214                   break_label = $4;
  215                 }
  216             | '{' statement_list '}'
  217                 { $$ = 0; }
  218             ;
  219 function        : Define NAME '(' opt_parameter_list ')' '{'
  220                   ENDOFLINE opt_auto_define_list 
  221                 { char *params, *autos;
  222                   check_params ($4,$8);
  223                   params = arg_str ($4);
  224                   autos = arg_str ($8);
  225                   set_genstr_size (30 + strlen (params)
  226                            + strlen (autos));
  227                   sprintf (genstr, "F%d,%s.%s[", lookup ($2,FUNCT),
  228                        params, autos);
  229                   generate (genstr);
  230                   free_args ($4);
  231                   free_args ($8);
  232                   $1 = next_label;
  233                   next_label = 0;
  234                 }
  235               statement_list ENDOFLINE '}'
  236                 {
  237                   generate ("0R]");
  238                   next_label = $1;
  239                 }
  240             ;
  241 opt_parameter_list  : /* empty */ 
  242                 { $$ = NULL; }
  243             | parameter_list
  244             ;
  245 parameter_list      : NAME
  246                 { $$ = nextarg (NULL, lookup ($1,SIMPLE), FALSE); }
  247             | define_list ',' NAME
  248                 { $$ = nextarg ($1, lookup ($3,SIMPLE), FALSE); }
  249             ;
  250 opt_auto_define_list    : /* empty */ 
  251                 { $$ = NULL; }
  252             | Auto define_list ENDOFLINE
  253                 { $$ = $2; } 
  254             | Auto define_list ';'
  255                 { $$ = $2; } 
  256             ;
  257 define_list         : NAME
  258                 { $$ = nextarg (NULL, lookup ($1,SIMPLE), FALSE); }
  259             | NAME '[' ']'
  260                 { $$ = nextarg (NULL, lookup ($1,ARRAY), FALSE); }
  261             | define_list ',' NAME
  262                 { $$ = nextarg ($1, lookup ($3,SIMPLE), FALSE); }
  263             | define_list ',' NAME '[' ']'
  264                 { $$ = nextarg ($1, lookup ($3,ARRAY), FALSE); }
  265             ;
  266 opt_argument_list   : /* empty */
  267                 { $$ = NULL; }
  268             | argument_list
  269             ;
  270 argument_list       : expression
  271                 { $$ = nextarg (NULL,0, FALSE); }
  272             | argument_list ',' expression
  273                 { $$ = nextarg ($1,0, FALSE); }
  274             ;
  275 relational_expression   : expression
  276                 { $$ = 0; }
  277             | expression REL_OP expression
  278                 {
  279                   $$ = 0;
  280                   switch (*($2))
  281                 {
  282                 case '=':
  283                   generate ("=");
  284                   break;
  285                 case '!':
  286                   generate ("#");
  287                   break;
  288                 case '<':
  289                   if ($2[1] == '=')
  290                     generate ("{");
  291                   else
  292                     generate ("<");
  293                   break;
  294                 case '>':
  295                   if ($2[1] == '=')
  296                     generate ("}");
  297                   else
  298                     generate (">");
  299                   break;
  300                 }
  301                 }
  302             ;
  303 return_expression   : /* empty */
  304                 {
  305                   $$ = 0;
  306                   generate ("0");
  307                 }
  308             | expression
  309             ;
  310 expression      : named_expression ASSIGN_OP 
  311                 {
  312                   if ($2 != '=')
  313                 {
  314                   if ($1 < 0)
  315                     sprintf (genstr, "DL%d:", -$1);
  316                   else
  317                     sprintf (genstr, "l%d:", $1);
  318                   generate (genstr);
  319                 }
  320                 }
  321               expression
  322                 {
  323                   $$ = 0;
  324                   if ($2 != '=')
  325                 {
  326                   sprintf (genstr, "%c", $2);
  327                   generate (genstr);
  328                 }
  329                   if ($1 < 0)
  330                 sprintf (genstr, "S%d:", -$1);
  331                   else
  332                 sprintf (genstr, "s%d:", $1);
  333                   generate (genstr);
  334                 }
  335             | expression '+' expression
  336                 { generate ("+"); }
  337             | expression '-' expression
  338                 { generate ("-"); }
  339             | expression '*' expression
  340                 { generate ("*"); }
  341             | expression '/' expression
  342                 { generate ("/"); }
  343             | expression '%' expression
  344                 { generate ("%"); }
  345             | expression '^' expression
  346                 { generate ("^"); }
  347             | '-' expression           %prec UNARY_MINUS
  348                 { generate ("n"); $$ = 1;}
  349             | named_expression
  350                 {
  351                   $$ = 1;
  352                   if ($1 < 0)
  353                 sprintf (genstr, "L%d:", -$1);
  354                   else
  355                 sprintf (genstr, "l%d:", $1);
  356                   generate (genstr);
  357                 }
  358             | NUMBER
  359                 {
  360                   int len = strlen ($1);
  361                   $$ = 1;
  362                   if (len == 1 && *$1 == '0')
  363                 generate ("0");
  364                   else
  365                 {
  366                   if (len == 1 && *$1 == '1')
  367                     generate ("1");
  368                   else
  369                     {
  370                       generate ("K");
  371                       generate ($1);
  372                       generate (":");
  373                     }
  374                   free ($1);
  375                 }
  376                 }
  377             | '(' expression ')'
  378                 { $$ = 1; }
  379             | NAME '(' opt_argument_list ')'
  380                 {
  381                   $$ = 1;
  382                   if ($3 != NULL)
  383                 { char *params = call_str ($3);
  384                   set_genstr_size (20 + strlen (params));
  385                   sprintf (genstr, "C%d,%s:",
  386                        lookup ($1,FUNCT), params);
  387                   free_args ($3);
  388                 }
  389                   else
  390                   sprintf (genstr, "C%d:", lookup ($1,FUNCT));
  391                   generate (genstr);
  392                 }
  393             | INCR_DECR named_expression
  394                 {
  395                   $$ = 1;
  396                   if ($2 < 0)
  397                 {
  398                   if ($1 == '+')
  399                     sprintf (genstr, "DA%d:L%d:", -$2, -$2);
  400                   else
  401                     sprintf (genstr, "DM%d:L%d:", -$2, -$2);
  402                 }
  403                   else
  404                 {
  405                   if ($1 == '+')
  406                     sprintf (genstr, "i%d:l%d:", $2, $2);
  407                   else
  408                     sprintf (genstr, "d%d:l%d:", $2, $2);
  409                 }
  410                   generate (genstr);
  411                 }
  412             | named_expression INCR_DECR
  413                 {
  414                   $$ = 1;
  415                   if ($1 < 0)
  416                 {
  417                   sprintf (genstr, "DL%d:x", -$1);
  418                   generate (genstr); 
  419                   if ($2 == '+')
  420                     sprintf (genstr, "A%d:", -$1);
  421                   else
  422                     sprintf (genstr, "M%d:", -$1);
  423                 }
  424                   else
  425                 {
  426                   sprintf (genstr, "l%d:", $1);
  427                   generate (genstr);
  428                   if ($2 == '+')
  429                     sprintf (genstr, "i%d:", $1);
  430                   else
  431                     sprintf (genstr, "d%d:", $1);
  432                 }
  433                   generate (genstr);
  434                 }
  435             | Length '(' expression ')'
  436                 { generate ("cL"); $$ = 1;}
  437             | Sqrt '(' expression ')'
  438                 { generate ("cR"); $$ = 1;}
  439             | Scale '(' expression ')'
  440                 { generate ("cS"); $$ = 1;}
  441             ;
  442 named_expression    : NAME
  443                 { $$ = lookup ($1,SIMPLE); }
  444             | NAME '[' expression ']'
  445                 { $$ = lookup ($1,ARRAY); }
  446             | Ibase
  447                 { $$ = 0; }
  448             | Obase
  449                 { $$ = 1; }
  450             | Scale
  451                 { $$ = 2; }
  452             ;
  453 
  454 %%