⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sbc.y

📁 操作系统源代码
💻 Y
字号:
, %{/* sbc.y: A POSIX bc processor written for minix with no extensions.  */ /*  This file is part of bc written for MINIX.    Copyright (C) 1991, 1992 Free Software Foundation, Inc.    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License , or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; see the file COPYING.  If not, write to    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.    You may contact the author by:       e-mail:  phil@cs.wwu.edu      us-mail:  Philip A. Nelson                Computer Science Department, 9062                Western Washington University                Bellingham, WA 98226-9062       *************************************************************************/#include "bcdefs.h"#include "global.h"     /* To get the global variables. */#include "proto.h"%}%start program%union {	char *s_value;	char  c_value;	int   i_value;	arg_list *a_value;       }%token <i_value> NEWLINE AND OR NOT%token <s_value> STRING NAME NUMBER/*     '-', '+' are tokens themselves		*/%token <c_value> MUL_OP/*     '*', '/', '%' 				*/%token <c_value> ASSIGN_OP/*     '=', '+=',  '-=', '*=', '/=', '%=', '^=' */%token <s_value> REL_OP/*     '==', '<=', '>=', '!=', '<', '>' 	*/%token <c_value> INCR_DECR/*     '++', '--' 				*/%token <i_value> Define    Break    Quit    Length/*     'define', 'break', 'quit', 'length' 	*/%token <i_value> Return    For    If    While    Sqrt  Else/*     'return', 'for', 'if', 'while', 'sqrt',  'else' 	*/%token <i_value> Scale    Ibase    Obase    Auto  Read/*     'scale', 'ibase', 'obase', 'auto', 'read' 	*/%token <i_value> Warranty, Halt, Last, Continue, Print, Limits/*     'warranty', 'halt', 'last', 'continue', 'print', 'limits'  *//* The types of all other non-terminals. */%type <i_value> expression named_expression return_expression%type <a_value> opt_parameter_list parameter_list opt_auto_define_list%type <a_value> define_list opt_argument_list argument_list%type <i_value> program input_item semicolon_list statement_list%type <i_value> statement_or_error statement function relational_expression /* precedence */%nonassoc REL_OP%right ASSIGN_OP%left '+' '-'%left MUL_OP%right '^'%nonassoc UNARY_MINUS%nonassoc INCR_DECR%%program			: /* empty */			    {			      $$ = 0;			      std_only = TRUE;			      if (interactive)				{				  printf ("s%s\n", BC_VERSION);				  welcome();				}			    }			| program input_item			;input_item		: semicolon_list NEWLINE			    { run_code(); }			| function			    { run_code(); }			| error NEWLINE			    {			      yyerrok; 			      init_gen() ;			    }			;semicolon_list		: /* empty */			    { $$ = 0; }			| statement_or_error			| semicolon_list ';' statement_or_error			| semicolon_list ';'			;statement_list		: /* empty */			    { $$ = 0; }			| statement			| statement_list NEWLINE			| statement_list NEWLINE statement			| statement_list ';'			| statement_list ';' statement			;statement_or_error	: statement			| error statement			    { $$ = $2; }			;statement 		: Warranty			    { warranty("s"); }			| expression			    {			      if ($1 & 1)				generate ("W");			      else				generate ("p");			    }			| STRING			    {			      $$ = 0;			      generate ("w");			      generate ($1);			      free ($1);			    }			| Break			    {			      if (break_label == 0)				yyerror ("Break outside a for/while");			      else				{				  sprintf (genstr, "J%1d:", break_label);				  generate (genstr);				}			    }			| Quit			    { exit(0); }			| Return			    { generate ("0R"); }			| Return '(' return_expression ')'			    { generate ("R"); }			| For 			    {			      $1 = break_label; 			      break_label = next_label++;			    }			  '(' expression ';'			    {			      $4 = next_label++;			      sprintf (genstr, "pN%1d:", $4);			      generate (genstr);			    }			  relational_expression ';'			    {			      $7 = next_label++;			      sprintf (genstr, "B%1d:J%1d:", $7, break_label);			      generate (genstr);			      $<i_value>$ = next_label++;			      sprintf (genstr, "N%1d:", $<i_value>$);			      generate (genstr);			    }			  expression ')'			    {			      sprintf (genstr, "pJ%1d:N%1d:", $4, $7);			      generate (genstr);			    }			  statement			    {			      sprintf (genstr, "J%1d:N%1d:", $<i_value>9,				       break_label);			      generate (genstr);			      break_label = $1;			    }			| If '(' relational_expression ')' 			    {			      $3 = next_label++;			      sprintf (genstr, "Z%1d:", $3);			      generate (genstr);			    }			  statement			    {			      sprintf (genstr, "N%1d:", $3); 			      generate (genstr);			    }			| While 			    {			      $1 = next_label++;			      sprintf (genstr, "N%1d:", $1);			      generate (genstr);			    }			'(' relational_expression 			    {			      $4 = break_label; 			      break_label = next_label++;			      sprintf (genstr, "Z%1d:", break_label);			      generate (genstr);			    }			')' statement			    {			      sprintf (genstr, "J%1d:N%1d:", $1, break_label);			      generate (genstr);			      break_label = $4;			    }			| '{' statement_list '}'			    { $$ = 0; }			;function 		: Define NAME '(' opt_parameter_list ')' '{'       			  NEWLINE opt_auto_define_list 			    {			      check_params ($4,$8);			      sprintf (genstr, "F%d,%s.%s[", lookup($2,FUNCT),				       arg_str ($4,TRUE), arg_str ($8,TRUE));			      generate (genstr);			      free_args ($4);			      free_args ($8);			      $1 = next_label;			      next_label = 0;			    }			  statement_list NEWLINE '}'			    {			      generate ("0R]");			      next_label = $1;			    }			;opt_parameter_list	: /* empty */ 			    { $$ = NULL; }			| parameter_list			;parameter_list 		: NAME			    { $$ = nextarg (NULL, lookup($1,SIMPLE)); }			| define_list ',' NAME			    { $$ = nextarg ($1, lookup($3,SIMPLE)); }			;opt_auto_define_list 	: /* empty */ 			    { $$ = NULL; }			| Auto define_list NEWLINE			    { $$ = $2; } 			| Auto define_list ';'			    { $$ = $2; } 			;define_list 		: NAME			    { $$ = nextarg (NULL, lookup($1,SIMPLE)); }			| NAME '[' ']'			    { $$ = nextarg (NULL, lookup($1,ARRAY)); }			| define_list ',' NAME			    { $$ = nextarg ($1, lookup($3,SIMPLE)); }			| define_list ',' NAME '[' ']'			    { $$ = nextarg ($1, lookup($3,ARRAY)); }			;opt_argument_list	: /* empty */			    { $$ = NULL; }			| argument_list			;argument_list 		: expression			    { $$ = nextarg (NULL,0); }			| argument_list ',' expression			    { $$ = nextarg ($1,0); }			;relational_expression	: expression			    { $$ = 0; }			| expression REL_OP expression			    {			      $$ = 0;			      switch (*($2))				{				case '=':				  generate ("=");				  break;				case '!':				  generate ("#");				  break;				case '<':				  if ($2[1] == '=')				    generate ("{");				  else				    generate ("<");				  break;				case '>':				  if ($2[1] == '=')				    generate ("}");				  else				    generate (">");				  break;				}			    }			;return_expression	: /* empty */			    {			      $$ = 0;			      generate ("0");			    }			| expression			;expression		: named_expression ASSIGN_OP 			    {			      if ($2 != '=')				{				  if ($1 < 0)				    sprintf (genstr, "DL%d:", -$1);				  else				    sprintf (genstr, "l%d:", $1);				  generate (genstr);				}			    }			  expression			    {			      $$ = 0;			      if ($2 != '=')				{				  sprintf (genstr, "%c", $2);				  generate (genstr);				}			      if ($1 < 0)				sprintf (genstr, "S%d:", -$1);			      else				sprintf (genstr, "s%d:", $1);			      generate (genstr);			    }			| expression '+' expression			    { generate ("+"); }			| expression '-' expression			    { generate ("-"); }			| expression MUL_OP expression			    {			      genstr[0] = $2;			      genstr[1] = 0;			      generate (genstr);			    }			| expression '^' expression			    { generate ("^"); }			| '-' expression           %prec UNARY_MINUS			    { generate ("n"); $$ = 1;}			| named_expression			    {			      $$ = 1;			      if ($1 < 0)				sprintf (genstr, "L%d:", -$1);			      else				sprintf (genstr, "l%d:", $1);			      generate (genstr);			    }			| NUMBER			    {			      int len = strlen($1);			      $$ = 1;			      if (len == 1 && *$1 == '0')				generate ("0");			      else				{				  if (len == 1 && *$1 == '1')				    generate ("1");				  else				    {				      generate ("K");				      generate ($1);				      generate (":");				    }				  free ($1);				}			    }			| '(' expression ')'			    { $$ = 1; }			| NAME '(' opt_argument_list ')'			    {			      $$ = 1;			      if ($3 != NULL)				{ 				  sprintf (genstr, "C%d,%s:", lookup($1,FUNCT),					   arg_str ($3,FALSE));				  free_args ($3);				}			      else				  sprintf (genstr, "C%d:", lookup($1,FUNCT));			      generate (genstr);			    }			| INCR_DECR named_expression			    {			      $$ = 1;			      if ($2 < 0)				{				  if ($1 == '+')				    sprintf (genstr, "DA%d:L%d:", -$2, -$2);				  else				    sprintf (genstr, "DM%d:L%d:", -$2, -$2);				}			      else				{				  if ($1 == '+')				    sprintf (genstr, "i%d:l%d:", $2, $2);				  else				    sprintf (genstr, "d%d:l%d:", $2, $2);				}			      generate (genstr);			    }			| named_expression INCR_DECR			    {			      $$ = 1;			      if ($1 < 0)				{				  sprintf (genstr, "DL%d:x", -$1);				  generate (genstr); 				  if ($2 == '+')				    sprintf (genstr, "A%d:", -$1);				  else				    sprintf (genstr, "M%d:", -$1);				}			      else				{				  sprintf (genstr, "l%d:", $1);				  generate (genstr);				  if ($2 == '+')				    sprintf (genstr, "i%d:", $1);				  else				    sprintf (genstr, "d%d:", $1);				}			      generate (genstr);			    }			| Length '(' expression ')'			    { generate ("cL"); $$ = 1;}			| Sqrt '(' expression ')'			    { generate ("cR"); $$ = 1;}			| Scale '(' expression ')'			    { generate ("cS"); $$ = 1;}			;named_expression	: NAME			    { $$ = lookup($1,SIMPLE); }			| NAME '[' expression ']'			    { $$ = lookup($1,ARRAY); }			| Ibase			    { $$ = 0; }			| Obase			    { $$ = 1; }			| Scale			    { $$ = 2; }			;%%

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -