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

📄 pic.y

📁 早期freebsd实现
💻 Y
📖 第 1 页 / 共 3 页
字号:
/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.     Written by James Clark (jjc@jclark.com)This file is part of groff.groff is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the FreeSoftware Foundation; either version 2, or (at your option) any laterversion.groff is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY orFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public Licensefor more details.You should have received a copy of the GNU General Public License alongwith groff; see the file COPYING.  If not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA. */%{#include "pic.h"#include "ptable.h"#include "object.h"extern int delim_flag;extern void do_copy(const char *);extern void copy_rest_thru(const char *, const char *);extern void copy_file_thru(const char *, const char *, const char *);extern void push_body(const char *);extern void do_for(char *var, double from, double to,		   int by_is_multiplicative, double by, char *body);extern void do_lookahead();#undef fmod#undef randextern "C" {  double fmod(double, double);  int rand();}/* Maximum number of characters produced by printf("%g") */#define GDIGITS 14int yylex();void yyerror(const char *);void reset(const char *nm);void reset_all();place *lookup_label(const char *);void define_label(const char *label, const place *pl);direction current_direction;position current_position;implement_ptable(place)PTABLE(place) top_table;PTABLE(place) *current_table = &top_table;saved_state *current_saved_state = 0;object_list olist;const char *ordinal_postfix(int n);const char *object_type_name(object_type type);char *format_number(const char *form, double n);char *do_sprintf(const char *form, const double *v, int nv);%}%union {	char *str;	int n;	double x;	struct { double x, y; } pair;	struct { double x; char *body; } if_data;	struct { char *str; const char *filename; int lineno; } lstr;	struct { double *v; int nv; int maxv; } dv;	struct { double val; int is_multiplicative; } by;	place pl;	object *obj;	corner crn;	path *pth;	object_spec *spec;	saved_state *pstate;	graphics_state state;	object_type obtype;}%token <str> LABEL%token <str> VARIABLE%token <x> NUMBER%token <lstr> TEXT%token <lstr> COMMAND_LINE%token <str> DELIMITED%token <n> ORDINAL%token TH%token LEFT_ARROW_HEAD%token RIGHT_ARROW_HEAD%token DOUBLE_ARROW_HEAD%token LAST%token UP%token DOWN%token LEFT%token RIGHT%token BOX%token CIRCLE%token ELLIPSE%token ARC%token LINE%token ARROW%token MOVE%token SPLINE%token HEIGHT%token RADIUS%token WIDTH%token DIAMETER%token UP%token DOWN%token RIGHT%token LEFT%token FROM%token TO%token AT%token WITH%token BY%token THEN%token DOTTED%token DASHED%token CHOP%token SAME%token INVISIBLE%token LJUST%token RJUST%token ABOVE%token BELOW%token OF%token THE%token WAY%token BETWEEN%token AND%token HERE%token DOT_N%token DOT_E	%token DOT_W%token DOT_S%token DOT_NE%token DOT_SE%token DOT_NW%token DOT_SW%token DOT_C%token DOT_START%token DOT_END%token DOT_X%token DOT_Y%token DOT_HT%token DOT_WID%token DOT_RAD%token SIN%token COS%token ATAN2%token LOG%token EXP%token SQRT%token K_MAX%token K_MIN%token INT%token RAND%token COPY%token THRU%token TOP%token BOTTOM%token UPPER%token LOWER%token SH%token PRINT%token CW%token CCW%token FOR%token DO%token IF%token ELSE%token ANDAND%token OROR%token NOTEQUAL%token EQUALEQUAL%token LESSEQUAL%token GREATEREQUAL%token LEFT_CORNER%token RIGHT_CORNER%token CENTER%token END%token START%token RESET%token UNTIL%token PLOT%token THICKNESS%token FILL%token ALIGNED%token SPRINTF%token COMMAND%token DEFINE%token UNDEF/* this ensures that plot 17 "%g" parses as (plot 17 "%g") */%left PLOT%left TEXT SPRINTF/* give text adjustments higher precedence than TEXT, so thatbox "foo" above ljust == box ("foo" above ljust)*/%left LJUST RJUST ABOVE BELOW%left LEFT RIGHT/* Give attributes that take an optional expression a higherprecedence than left and right, so that eg `line chop left'parses properly. */%left CHOP DASHED DOTTED UP DOWN FILL%left LABEL%left VARIABLE NUMBER '(' SIN COS ATAN2 LOG EXP SQRT K_MAX K_MIN INT RAND LAST %left ORDINAL HERE '`'/* these need to be lower than '-' */%left HEIGHT RADIUS WIDTH DIAMETER FROM TO AT THICKNESS/* these must have higher precedence than CHOP so that `label %prec CHOP'works */%left DOT_N DOT_E DOT_W DOT_S DOT_NE DOT_SE DOT_NW DOT_SW DOT_C%left DOT_START DOT_END TOP BOTTOM LEFT_CORNER RIGHT_CORNER%left UPPER LOWER CENTER START END%left ','%left OROR%left ANDAND%left EQUALEQUAL NOTEQUAL%left '<' '>' LESSEQUAL GREATEREQUAL%left BETWEEN OF%left AND%left '+' '-'%left '*' '/' '%'%right '!'%right '^'%type <x> expr any_expr text_expr%type <by> optional_by%type <pair> expr_pair position_not_place%type <if_data> simple_if%type <obj> nth_primitive%type <crn> corner%type <pth> path label_path relative_path%type <pl> place label element element_list middle_element_list%type <spec> object_spec%type <pair> position%type <obtype> object_type%type <n> optional_ordinal_last ordinal%type <str> until%type <dv> sprintf_args%type <lstr> text print_args print_arg%%top:	optional_separator	| element_list		{		  if (olist.head)		    print_picture(olist.head);		}	;element_list:	optional_separator middle_element_list optional_separator		{ $$ = $2; }	;middle_element_list:	element		{ $$ = $1; }	| middle_element_list separator element		{ $$ = $1; }	;optional_separator:	/* empty */	| separator	;separator:	';'	| separator ';'	;placeless_element:	VARIABLE '=' any_expr		{		  define_variable($1, $3);		  a_delete $1;		}	| VARIABLE ':' '=' any_expr		{		  place *p = lookup_label($1);		  if (!p) {		    lex_error("variable `%1' not defined", $1);		    YYABORT;		  }		  p->obj = 0;		  p->x = $4;		  p->y = 0.0;		  a_delete $1;		}	| UP		{ current_direction = UP_DIRECTION; }	| DOWN		{ current_direction = DOWN_DIRECTION; }	| LEFT		{ current_direction = LEFT_DIRECTION; }	| RIGHT		{ current_direction = RIGHT_DIRECTION; }	| COMMAND_LINE		{		  olist.append(make_command_object($1.str, $1.filename,						   $1.lineno));		}	| COMMAND print_args		{		  olist.append(make_command_object($2.str, $2.filename,						   $2.lineno));		}	| PRINT print_args		{		  fprintf(stderr, "%s\n", $2.str);		  a_delete $2.str;	          fflush(stderr);		}	| SH		{ delim_flag = 1; }	  DELIMITED		{		  delim_flag = 0;		  system($3);		  a_delete $3;		}	| COPY TEXT		{		  if (yychar < 0)		    do_lookahead();		  do_copy($2.str);		  // do not delete the filename		}	| COPY TEXT THRU		{ delim_flag = 2; }	  DELIMITED 		{ delim_flag = 0; }	  until		{		  if (yychar < 0)		    do_lookahead();		  copy_file_thru($2.str, $5, $7);		  // do not delete the filename		  a_delete $5;		  a_delete $7;		}	| COPY THRU		{ delim_flag = 2; }	  DELIMITED		{ delim_flag = 0; }	  until		{		  if (yychar < 0)		    do_lookahead();		  copy_rest_thru($4, $6);		  a_delete $4;		  a_delete $6;		}	| FOR VARIABLE '=' expr TO expr optional_by DO	  	{ delim_flag = 1; }	  DELIMITED	  	{		  delim_flag = 0;		  if (yychar < 0)		    do_lookahead();		  do_for($2, $4, $6, $7.is_multiplicative, $7.val, $10); 		}	| simple_if		{		  if (yychar < 0)		    do_lookahead();		  if ($1.x != 0.0)		    push_body($1.body);		  a_delete $1.body;		}	| simple_if ELSE		{ delim_flag = 1; }	  DELIMITED		{		  delim_flag = 0;		  if (yychar < 0)		    do_lookahead();		  if ($1.x != 0.0)		    push_body($1.body);		  else		    push_body($4);		  a_delete $1.body;		  a_delete $4;		}	| reset_variables	| RESET		{ define_variable("scale", 1.0); }	;reset_variables:	RESET VARIABLE		{ reset($2); a_delete $2; }	| reset_variables VARIABLE		{ reset($2); a_delete $2; }	| reset_variables ',' VARIABLE		{ reset($3); a_delete $3; }	;print_args:	print_arg		{ $$ = $1; }	| print_args print_arg		{		  $$.str = new char[strlen($1.str) + strlen($2.str) + 1];		  strcpy($$.str, $1.str);		  strcat($$.str, $2.str);		  a_delete $1.str;		  a_delete $2.str;		  if ($1.filename) {		    $$.filename = $1.filename;		    $$.lineno = $1.lineno;		  }		  else if ($2.filename) {		    $$.filename = $2.filename;		    $$.lineno = $2.lineno;		  }		}	;print_arg:  	expr               %prec ','		{		  $$.str = new char[GDIGITS + 1];		  sprintf($$.str, "%g", $1);		  $$.filename = 0;		  $$.lineno = 0;		}	| text		{ $$ = $1; }	| position          %prec ','		{		  $$.str = new char[GDIGITS + 2 + GDIGITS + 1];		  sprintf($$.str, "%g, %g", $1.x, $1.y);		  $$.filename = 0;		  $$.lineno = 0;		}simple_if:	IF any_expr THEN		{ delim_flag = 1; }	DELIMITED		{ delim_flag = 0; $$.x = $2; $$.body = $5; }	;until:	/* empty */		{ $$ = 0; }	| UNTIL TEXT		{ $$ = $2.str; }	;	any_expr:	expr		{ $$ = $1; }	| text_expr		{ $$ = $1; }	;	text_expr:	text EQUALEQUAL text		{		  $$ = strcmp($1.str, $3.str) == 0;		  a_delete $1.str;		  a_delete $3.str;		}	| text NOTEQUAL text		{		  $$ = strcmp($1.str, $3.str) != 0;		  a_delete $1.str;		  a_delete $3.str;		}	| text_expr ANDAND text_expr		{ $$ = ($1 != 0.0 && $3 != 0.0); }	| text_expr ANDAND expr		{ $$ = ($1 != 0.0 && $3 != 0.0); }	| expr ANDAND text_expr		{ $$ = ($1 != 0.0 && $3 != 0.0); }	| text_expr OROR text_expr		{ $$ = ($1 != 0.0 || $3 != 0.0); }	| text_expr OROR expr		{ $$ = ($1 != 0.0 || $3 != 0.0); }	| expr OROR text_expr		{ $$ = ($1 != 0.0 || $3 != 0.0); }	| '!' text_expr		{ $$ = ($2 == 0.0); }	;optional_by:	/* empty */		{ $$.val = 1.0; $$.is_multiplicative = 0; }	| BY expr		{ $$.val = $2; $$.is_multiplicative = 0; }	| BY '*' expr		{ $$.val = $3; $$.is_multiplicative = 1; }	;element:	object_spec		{		  $$.obj = $1->make_object(&current_position,					   &current_direction);		  if ($$.obj == 0)		    YYABORT;		  delete $1;		  if ($$.obj)		    olist.append($$.obj);		  else {		    $$.x = current_position.x;		    $$.y = current_position.y;		  }		}	| LABEL ':' optional_separator element		{ $$ = $4; define_label($1, & $$); a_delete $1; }	| LABEL ':' optional_separator position_not_place		{		  $$.obj = 0;		  $$.x = $4.x;		  $$.y = $4.y;		  define_label($1, & $$);		  a_delete $1;		}	| LABEL ':' optional_separator place		{		  $$ = $4;		  define_label($1, & $$);		  a_delete $1;		}	| '{'		{		  $<state>$.x = current_position.x;		  $<state>$.y = current_position.y;		  $<state>$.dir = current_direction;		}	  element_list '}'		{		  current_position.x = $<state>2.x;		  current_position.y = $<state>2.y;		  current_direction = $<state>2.dir;		}	  optional_element		{		  $$ = $3;		}	| placeless_element		{		  $$.obj = 0;		  $$.x = current_position.x;		  $$.y = current_position.y;		}	;optional_element:	/* empty */		{}	| element		{}	;object_spec:	BOX		{		  $$ = new object_spec(BOX_OBJECT);		}	| CIRCLE

⌨️ 快捷键说明

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