2 /* sbc.y: A POSIX bc processor written for minix with no extensions. */
4 /* This file is part of GNU bc.
5 Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
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.
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.
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, 675 Mass Ave, Cambridge, MA 02139, USA.
21 You may contact the author by:
22 e-mail: phil@cs.wwu.edu
23 us-mail: Philip A. Nelson
24 Computer Science Department, 9062
25 Western Washington University
26 Bellingham, WA 98226-9062
28 *************************************************************************/
31 #include "global.h" /* To get the global variables. */
44 %token <i_value> NEWLINE AND OR NOT
45 %token <s_value> STRING NAME NUMBER
46 /* '-', '+' are tokens themselves */
47 %token <c_value> ASSIGN_OP
48 /* '=', '+=', '-=', '*=', '/=', '%=', '^=' */
49 %token <s_value> REL_OP
50 /* '==', '<=', '>=', '!=', '<', '>' */
51 %token <c_value> INCR_DECR
53 %token <i_value> Define Break Quit Length
54 /* 'define', 'break', 'quit', 'length' */
55 %token <i_value> Return For If While Sqrt Else
56 /* 'return', 'for', 'if', 'while', 'sqrt', 'else' */
57 %token <i_value> Scale Ibase Obase Auto Read
58 /* 'scale', 'ibase', 'obase', 'auto', 'read' */
59 %token <i_value> Warranty, Halt, Last, Continue, Print, Limits
60 /* 'warranty', 'halt', 'last', 'continue', 'print', 'limits' */
62 /* The types of all other non-terminals. */
63 %type <i_value> expression named_expression return_expression
64 %type <a_value> opt_parameter_list parameter_list opt_auto_define_list
65 %type <a_value> define_list opt_argument_list argument_list
66 %type <i_value> program input_item semicolon_list statement_list
67 %type <i_value> statement_or_error statement function relational_expression
85 printf ("s%s\n", BC_VERSION);
91 input_item : semicolon_list NEWLINE
101 semicolon_list : /* empty */
104 | semicolon_list ';' statement_or_error
107 statement_list : /* empty */
110 | statement_list NEWLINE
111 | statement_list NEWLINE statement
113 | statement_list ';' statement
115 statement_or_error : statement
137 if (break_label == 0)
138 yyerror ("Break outside a for/while");
141 sprintf (genstr, "J%1d:", break_label);
149 | Return '(' return_expression ')'
154 break_label = next_label++;
159 sprintf (genstr, "pN%1d:", $4);
162 relational_expression ';'
165 sprintf (genstr, "B%1d:J%1d:", $7, break_label);
167 $<i_value>$ = next_label++;
168 sprintf (genstr, "N%1d:", $<i_value>$);
173 sprintf (genstr, "pJ%1d:N%1d:", $4, $7);
178 sprintf (genstr, "J%1d:N%1d:", $<i_value>9,
183 | If '(' relational_expression ')'
186 sprintf (genstr, "Z%1d:", $3);
191 sprintf (genstr, "N%1d:", $3);
197 sprintf (genstr, "N%1d:", $1);
200 '(' relational_expression
203 break_label = next_label++;
204 sprintf (genstr, "Z%1d:", break_label);
209 sprintf (genstr, "J%1d:N%1d:", $1, break_label);
213 | '{' statement_list '}'
216 function : Define NAME '(' opt_parameter_list ')' '{'
217 NEWLINE opt_auto_define_list
219 check_params ($4,$8);
220 sprintf (genstr, "F%d,%s.%s[", lookup($2,FUNCT),
221 arg_str ($4), arg_str ($8));
228 statement_list NEWLINE '}'
234 opt_parameter_list : /* empty */
238 parameter_list : NAME
239 { $$ = nextarg (NULL, lookup($1,SIMPLE), FALSE); }
240 | define_list ',' NAME
241 { $$ = nextarg ($1, lookup($3,SIMPLE), FALSE); }
243 opt_auto_define_list : /* empty */
245 | Auto define_list NEWLINE
247 | Auto define_list ';'
251 { $$ = nextarg (NULL, lookup($1,SIMPLE), FALSE); }
253 { $$ = nextarg (NULL, lookup($1,ARRAY), FALSE); }
254 | define_list ',' NAME
255 { $$ = nextarg ($1, lookup($3,SIMPLE), FALSE); }
256 | define_list ',' NAME '[' ']'
257 { $$ = nextarg ($1, lookup($3,ARRAY), FALSE); }
259 opt_argument_list : /* empty */
263 argument_list : expression
264 { $$ = nextarg (NULL,0, FALSE); }
265 | argument_list ',' expression
266 { $$ = nextarg ($1,0, FALSE); }
268 relational_expression : expression
270 | expression REL_OP expression
296 return_expression : /* empty */
303 expression : named_expression ASSIGN_OP
308 sprintf (genstr, "DL%d:", -$1);
310 sprintf (genstr, "l%d:", $1);
319 sprintf (genstr, "%c", $2);
323 sprintf (genstr, "S%d:", -$1);
325 sprintf (genstr, "s%d:", $1);
328 | expression '+' expression
330 | expression '-' expression
332 | expression '*' expression
334 | expression '/' expression
336 | expression '%' expression
338 | expression '^' expression
340 | '-' expression %prec UNARY_MINUS
341 { generate ("n"); $$ = 1;}
346 sprintf (genstr, "L%d:", -$1);
348 sprintf (genstr, "l%d:", $1);
353 int len = strlen($1);
355 if (len == 1 && *$1 == '0')
359 if (len == 1 && *$1 == '1')
372 | NAME '(' opt_argument_list ')'
377 sprintf (genstr, "C%d,%s:", lookup($1,FUNCT),
382 sprintf (genstr, "C%d:", lookup($1,FUNCT));
385 | INCR_DECR named_expression
391 sprintf (genstr, "DA%d:L%d:", -$2, -$2);
393 sprintf (genstr, "DM%d:L%d:", -$2, -$2);
398 sprintf (genstr, "i%d:l%d:", $2, $2);
400 sprintf (genstr, "d%d:l%d:", $2, $2);
404 | named_expression INCR_DECR
409 sprintf (genstr, "DL%d:x", -$1);
412 sprintf (genstr, "A%d:", -$1);
414 sprintf (genstr, "M%d:", -$1);
418 sprintf (genstr, "l%d:", $1);
421 sprintf (genstr, "i%d:", $1);
423 sprintf (genstr, "d%d:", $1);
427 | Length '(' expression ')'
428 { generate ("cL"); $$ = 1;}
429 | Sqrt '(' expression ')'
430 { generate ("cR"); $$ = 1;}
431 | Scale '(' expression ')'
432 { generate ("cS"); $$ = 1;}
434 named_expression : NAME
435 { $$ = lookup($1,SIMPLE); }
436 | NAME '[' expression ']'
437 { $$ = lookup($1,ARRAY); }